PDA

View Full Version : Same color choices for multiple components


petkusj@virtualight.com
01-11-2008, 09:54 PM
I'm trying to create a bunch of components that all share the same possible color values (ex: DK_ORANGE, LT_ORANGE, DK_BLUE, etc.) and I want the user (me) to be able to pick the specific value for each instance of the component in the parameter inspector.

I know how to add an Inspectable Color popup for a component, but that won't give me predefined colors that all the components/instance share.

So, I've come up with three ways to approach this problem and I'd appreciate advice on which path to take.

1. Find a way to connect the an Inspectable's enumeration to an array defined in an imported class. I don't think this works because the only example I've found of metadata using an external class is Collection, and I think all you're doing is defining the structure of the data the user will add to the Collection, not creating predefined data.

2. Create an Inspectable (list or array) in one class and import into another, but since Inspectables aren't properties, I don't see how this will work. I realize the getter and setter are methods and thus accessible, but I don't see them showing up in the parameter inspector.

3. Add items to an Inspectable (list or array) programmatically. In other words, create an addItem function that I can call when my component classes are initialized. The only way that I can think of doing this is to use a document class, which triggers the addItem function of each component, sending each one the same parameters so that all the instances will have the same approved list of colors.

Again, any nudge in the right direction would be greatly appreciated.

Thanks, Jennifer

petkusj@virtualight.com
01-13-2008, 12:48 AM
Ah, replying to myself again ...

So far, the only solution I've come up with is to I define the Inspectable/List/Array/whatever in a base class, and all the other component classes extend that class. Which was my original intention, but the base class was getting a little busy, so I wanted to break out the Inspectables into another class.

I was hoping a class could extend more than one class (even though I knew it couldn't) or that importing a class would also import the Inspectables of that class (which I don't think it does).

And this was all because I wanted to have lots of little classes instead of one big class. So if there are any suggestions, I'd still appreciate it.

Thanks, Jennifer

petkusj@virtualight.com
01-13-2008, 07:58 PM
OK, I've made a lot of progress and can now comfortably inherit my Inspectable list from a base class.

Now my problem is that a list contains strings, not ColorTransforms.

[Inspectable(type="List", enumeration="ORANGE_DARK,BLUE_DARK", defaultValue="ORANGE_DARK", name="Color:")]
public function set labelcolor(value:String):void {
changeLabelColor(ColorTransform(value));
}

So, how do I cast the String that the Inspectable expects into the ColorTransform that my changeLabelColor functions expects?

Thanks, Jennifer

PS My color choices are declared as constants of type ColorTransform in the form ORANGE_DARK.color = 0x993300;

petkusj@virtualight.com
01-13-2008, 09:28 PM
Well, at least now I know why this[value] didn't work.

I thought I'd be clever and declare my ColorTransform constants as static. So, the this[value] that's sent to my changeLabelColor function wouldn't work because the instance of my component didn't specifically have an ORANGE_DARK constant but the class did.

But since I want all my components to have the came ColorTransform constants, static still seems the best bet. So, can anyone tell me how to do the this[value] trick for a property that exists for the class and not specifically for an instance?

Thanks,

Jennifer

petkusj@virtualight.com
01-13-2008, 09:48 PM
Ooohh, so close. I can use

[Inspectable(type="List", enumeration="ORANGE_DARK,BLUE_DARK", defaultValue="ORANGE_DARK", name="Color:")]
public function set labelcolor(value:String):void {
changeLabelColor(componentClass[value]);
}

where componentClass is the name of the class and thus evaluate the String that is value as the static constant ORANGE_DARK or BLUE_DARK that the user picks in the parameter inspector for the instance.

In other words, componentClass[value] just turns into the static constant ORANGE_DARK.

But actually having to type in the name of the class seems limiting. What if I change the name of the class? I would have to remember to change the name of the setter.

I wouldn't have this problem if I didn't make the constants static. Am I just mistaken in thinking this is best practice?

Thanks,

Jennifer

petkusj@virtualight.com
01-16-2008, 01:26 AM
I got it working! I probably had it working a long time ago but I didn't realize that static-declared variables/constants aren't inherited by subclasses. D'oh!

So, here's what I did. I created the Inspectables tag in the base class:

[Inspectable(type="List", enumeration="ORANGE,BLUE,BLACK,WHITE", defaultValue="ORANGE", name="Font color:")]
public function set setBackGroundColor (value:String):void {
_backgroundcolor = this[value];
dispatchEvent(new myEvents(myEvents.PARAMETER_CHANGE, false, false));
}

Notice that there's a event that's dispatched when setFontColor is called. That event is defined in a simple event class that imports/extends Event and creates the following constant.

public static const PARAMETER_CHANGE:String = "labelColorChange";

I also update the protected variable _backgroundcolor with the value obtained in the setter. Of course, I have to evaluate the string variable value as one of the constants (ORANGE,BLUE, etc) that I defined at the top of the base class.

My component class (which extends the base class) then has an addEventListener in the configUI function. (I've set the base to import/extend UIComponent so I can take advantage of the built-in invalidation method.) Here's the addEventListener:

addEventListener(myEvents.PARAMETER_CHANGE,paramet erChange);

And all parameterChange function does is call invalidate(), which in turn calls the draw() function. (It's named draw(), of course, because that's the function name in the base class that I'm overriding. And in turn, the base class is overriding the draw() function that's defined in Adobe's fl.core.UIComponent class that the base class is extending.

It seems like a lot of running around to perform a simple task, but at least now all my Inspectables are in my base class and available to all the components that extend that base class.

I still have a few ways to screw up, however. I've created my color constants at the top of the class and later I have several Inspectables that populate enumerations with those same color constant names. But it would be a lot easier if I could make an array with those constants and populate the enumerations from that array.

But this is still quite workable. I hope my fumblings might help somebody else.

Jennifer