Forums > MaxMSP

Programmatic control of abstraction color

February 28, 2013 | 11:03 pm

Is it possible to change the color of an abstraction or a subpatcher from inside that abstraction or subpatcher respectively?

I’m building mechanism to allow me to block midi and/or audio processing for small collections of objects within a single patcher window and it would be useful to be able to change the color of an abstraction that is currently disabled without having to use bpatchers


March 1, 2013 | 4:00 am

By the way, I tried creating a js object inside an abstraction and by writing

patcher.name

I was able to retrieve the name of the abstraction so presumably I should be able to set attributes of it as well.

I noted that I could type

patcher.bgcolor(1,0,1,1) // Didn’t matter what I specified for args

without getting an error but I can’t figure out how I’m supposed to represent the 4 values of a color or even if it will work.


March 1, 2013 | 1:17 pm

That changes the color of an open (but locked) patcher. That’s not what I want.

Suppose I have an abstraction called mycolor

– Pasted Max Patch, click to expand. –

Now I have another patcher that contains [mycolor] as an object. I want to change the color of that object itself, not the patcher inside it.

– Pasted Max Patch, click to expand. –

March 1, 2013 | 3:33 pm

I’ll change it any way that works. The bgcolor object seems to change the background color of the OPENED abstraction patcher window but it doesn’t change the background color of the abstraction itself.

E.g, when you select an object in a patcher, you can go to the object inspector and change attributes such as its border, background color, font, and so forth. I want to be able to do (or at least control such changes) from inside the abstraction.


March 1, 2013 | 7:25 pm

This could probably be made simpler with more use of js. First, save this as "color_change_abstraction" –

– Pasted Max Patch, click to expand. –

Now here’s the patch that uses it –

– Pasted Max Patch, click to expand. –

March 1, 2013 | 11:52 pm

Works with [thispatcher] and the "bgcolor" message (NOT the [bgcolor] object). To change the border, use "bordercolor", to change text color it’s "textcolor".

The documentation is incorrect—it claims it needs a "color" message and doesn’t document the ability to use "bgcolor". Using "color" in this way gives an error: newobj: extra arguments.

I don’t know why some of the "Common Attributes" for jbox can be accessed directly (with patch cords) and some have to go through [thisptacher]…?

Works the same with subpatchers or abstractions.

– Pasted Max Patch, click to expand. –

March 2, 2013 | 4:59 am

Thank you all so much for your suggestions, they’re really appreciated.

The only one that is viable for me is the one suggested by nicolas danet where the border of an abstraction can be changed from the inside of that abstraction without the need for any external naming or references. All the others require external machinery as well as having to give each abstraction a script name.

I’ll settle for being able to change just the border via that borderindex although obviously I’d like to be able to change the background color as well since that’s a more visibly obvious indicator.


March 2, 2013 | 2:08 pm

What exactly does quecbec do? From the simple example, it looks like it’s capable of far more than just setting colors and positions. I downloaded the package from git but couldn’t find any documentation about it.

Unfortunately, it has one drawback for my purposes compared to the javascript example and that is that it can only reach the abstraction inside of which it directly lives.

With the javascript example I can use parentpatcher to climb up a nested tree so that if the code that needs to change the color of a higher level abstraction (normally top level of course) is deeply nested (because it itself is in an abstraction to avoid clutter), then I can still reach the top level object from it.

Quecbec would certainly be nicer because of the finer control of color but unless there’s a way to tell quecbec to traverse the tree, it’s not quite as useful as I would have to include extra mechanism to communicate with it if it can only live directly inside the abstraction. However, It will certainly be very helpful for just setting the default color of particular abstractions when they are loaded so that I don’t have to use the inspector everytime.

I have to say I REALLY appreciate all the suggestions coming here —


March 2, 2013 | 2:38 pm

Where is colorindex defined? Can I change the mappings? I browsed around in the Cycling ’74 support folder but didn’t come across anything that looked like a definition of these colors


March 2, 2013 | 4:36 pm

Yeah, I have a standard javascript function that allows me to return a reference to a patcher at an arbitrary level above where I am…..very convenient for targeting messages to precisely the right place.

I recognize colorindex may not be supported but I was hoping that there was a file with the index mappings somewhere in the Max folder so that I could change them.


March 2, 2013 | 5:17 pm

Send and Receive is precisely how I would be controlling it anyway — but I don’t want to populate every single abstraction with those three objects as well as all the other functionality needed to perform the test to see what color is required for the top-level abstraction

I want to make those objects be a single new abstraction that would take a parameter or two. That won’t work unless I can "reach" the higher level abstraction.


March 6, 2013 | 6:50 pm

First of all, thank you so much for making the change to your object.

Unfortunately, it’s still not quite sufficient to do what I need — it has to be able to address the patcher "above", even if that isn’t the very topmost patcher. (I think I was slightly less clear in my previous posting where I said "top-level abstraction", I probably should have called it "parent-level abstraction".

So let me explain much more clearly what it is that I am doing. I do have this working using javascript but I’m restricted to those 16 index colors so I’m still hoping your object could be used to address the need (and it turns out there are multiple uses for this feature, including the ability to have automatic default border colors based on particular abstractions, which is VERY handy)

I’m using MaxMSP to manage a live performance situation where, for each song, Max loads patchers containing both MIDI and audio routings and transformations. For example, here is a picture of the routing used to play a song called Shine

http://i.imgur.com/iW14BDF.jpg

Those brown objects are ‘virtual’ MIDI inputs that encapsulate underlying [midiin] and [midiparse] objects associated with specific external MIDI devices. As you can see (if you look :-), the same virtual input device may show up multiple times, possibly going through a [KeyboardLayer] so that only a part of the keyboard gets through – this allows easily layering and splits. In a complicated setup, the same named virtual input may show up in multiple places, simply so as to avoid spagetti wiring. Ultimately, the possibly processed MIDI arrives at a one of many kinds RED objects representing both external synths as well as internal (suitably encapsulated) VSTs.

Now, the problem I have run into recently is that I have to perform 2 or 3 songs that have transitions and so I cannot load in new patchers since it causes an audio glitch. So I need to have the patchers for all songs in question loaded in one go. Now, ideally it would be perfect to have the collection of abstractions for each song just live in a subpatcher and then the loaded patch would simply contain those three subpatchers. Unfortunately, there is no way to control which of those subpatchers is "active". Turns out that (as far as I can tell), patcher "active/inactive" stuff really only turns on or off an actual [midiin] object and since there aren’t actually explicit [midiin] objects, it’s not possible to turn a subpatcher on or off. I have never been able find a way to actually disable all event processing at a patcher level.

So, my solution was to modify those virtual MIDI inputs (and a couple of other non-MIDI related objects) to include a new [PassThru] filter that receives a name from a globally named [send] and if that name matches the name (actually a regex) associated with the specific [PassThru], then data is allowed through. So by globally transmitting the appropriate message, I can turn on or off sections of a patcher.

Now that that works, I created another abstraction, called [ControlParentAbstractionBorderColor] which takes as its parameter a name. When a name is received, that abstraction will, through a [js] object set the border color of its containing abstraction (typically the virtual midi input abstraction) to show whether it is enabled or not. What’s important here is that the javascript object returns the immediate parent, not the very top level patcher.

This works beautifully. Now, if that virtual midi input is at the top level, then a function such as "TopPatcher" would be fine. However, it turns out that because there are typically many objects per song, having three sets of objects becomes hard to manage and so I want to encapsulate each set of objects in its own subpatcher. That means I want to be able to cause that subpatcher abstraction itself to display in a different color depending on whether it’s the "active one".
So inserting a [ControlParentAbstractionBorderColor] object into each subpatcher will do the trick, but again it depends on being able to reach the immediate parent, not the top-level patcher.

So, here for example is the Javascript code I"m using. As you can see, it simply requires a message to be sent to borderColorAtParentLevel with the parameters 1 (for immediate parent) and a color. However, I’d love to be able to use rgb colors and I’d also love to be able to change the actual background color as well.

Thanks for your indulgence.

function patcherAtParentLevel(level)
{
   var p = this.patcher;
   while (level > 0 && p.parentpatcher)
      {
         p = p.parentpatcher;
         level--;
      }
   return p;
}

function borderColorAtParentLevel(level, indexcolor)
{
   var p = patcherAtParentLevel(level);
   p.box.colorindex = indexcolor;
}

March 7, 2013 | 6:11 pm

At first, I thought what you did was the wrong way around because I saw the command being sent into the patcher and the whole point is to NOT have to do that.

But after looking at it, I realized what you did and I made another example using your quebec that works EXACTLY the way I need from the inside. Take a look at this contrived example.

Thank you so much — this is much better than using colorindex — your effort is very much appreciated. I’m going to switch my patchers to use quebec now.

(By the way, why is it called quebec?)

– Pasted Max Patch, click to expand. –

March 7, 2013 | 8:40 pm

Can I change the background color? (As they say, no good deed goes unpunished!!!)


March 7, 2013 | 10:07 pm

Never mind — I read your last reply more closely and noted "all attributes"

This is beautiful.


March 15, 2013 | 10:23 pm

Terrific — I’ve deployed this to my entire live system and it works great, both for my recent need to display what abstractions are active as well as for the more general ability to have default coloring for different abstractions, which makes it much easier to view a complex patch.


Viewing 16 posts - 1 through 16 (of 16 total)