Lanny McNie

As the dev mgr, Lanny oversees the technical day-to-day details of production and makes sure things get out the door.

@astrostyle

CS3 Component bug: Component Styles

I was reminded a few weeks ago by Phil Chung (of philterdesign fame) of a bug in the CS3 component framework which we encountered shortly after CS3 was released.

Basically it boils down to setting component-level styles before any components of that type have been created. The styles are created, but when the first component of that type is instantiated, it resets the component styles, and overwrites the changes that were made beforehand. Slap a button in the library of a new FLA, and add the following code:

import fl.controls.Button;
import fl.managers.StyleManager;
var tf:TextFormat = new TextFormat();
tf.color = 0xff0000;
StyleManager.setComponentStyle(Button, "textFormat", tf);
var b:Button = new Button();
addChild(b);

There is an easy workaround, which is to make sure you set component styles *after* a component of that type has been instantiated. You can also just create a dummy instance of the component, and destroy it (which properly creates the style definition) and eliminate the issue.

You can download this fix here. One thing to note is that the components do not compile based on the component source code that is included with CS3, but rather the compiled componentShim component included in each component. To use this updated class, drop it in the appropriate directory (fl/managers) relative to your project, or in any path that is part of your publish class paths. The components will prefer any class definition found locally over the componentShim.
Please note that this is not officially supported by Adobe, and we take no responsibility for its use.

So there you have it. I imagine at some point, an updated release of the components will solve this and other issues, but until then at least this issue is resolved.

GPSD’07 Results are in!

Halloween has come and gone again, so it’s time to tally the votes and declare a winner. For the second time in 4 years, Wes and Kyle emerged as winners, with the “Girl Next Door” winning with 89 votes (35%).

“The interns” Nick and Eddie pulled on your 80’s nostalgia heart strings, bringing the Deceptikin in to 2nd place with 65 votes (25%). The Teenage Mutant Ninja Pumpkin by Ryan and Lanny, try as it might, could not overtake the transformers, and came in to a close 3rd place with 61 votes (24%). In last place, Michael and Sebastian’s Mac o’Lantern failed to invoke the fanboy support it expected with 39 votes (15%). It probably did better than a Windows pumpkin would have done in any case.

So that’s it. Back to labor and toil for the gskinner boys. To wrap up this year’s festivities, here is the aftermath of the desecrated pumpkins. This year we left them outside to avoid the pumpkin smell and fruit flies, so assumedly they held up longer than last year.

Thanks to all who voted!

The Great Pumpkin Showdown ’07

One of our favorite non-flash events here at gskinner.com is the pumpkin carving contest. This year was no exception, and we split into 4 teams (in order of seniority), and converted ordinary squash into ordinary squash with holes and a candle, which is just as good an excuse as any to drink beer and eat copious amounts of sugar at 2:45 on a Wednesday.

Unfortunately, even though our company grew. the number of entries is the same as last year. Grant and his wife are galavanting around Europe, so not only did they miss out on the festivities, but we missed out on Bobi’s yummy halloween goodies (and their company of course).

Continue reading →

Building a Static EventDispatcher in AS3

One of my favorite features of AS3 is the low-level inclusion of EventDispatcher in the AS3 framework. I do not miss the days of including EventDispatcher mix-ins in 80% of my classes in 100% of my projects. I especially like the additional features of the AS3 EventDispatcher: cancellation, custom event types (built in), preventDefault, event phases, etc.

However we have had several AS3 projects that have had a need for an EventDispatcher that is not instance-based. So, without further ado, here is an approach that we have used since our AS2 days:

package {
import flash.events.EventDispatcher;
public class MyClass {
protected static var disp:EventDispatcher;
public static function addEventListener(...p_args:Array):void {
if (disp == null) { disp = new EventDispatcher(); }
disp.addEventListener.apply(null, p_args);
}
public static function removeEventListener(...p_args:Array):void {
if (disp == null) { return; }
disp.removeEventListener.apply(null, p_args);
}
public static function dispatchEvent(...p_args:Array):void {
if (disp == null) { return; }
disp.dispatchEvent.apply(null, p_args);
}
// Other class code
}
}

Note that this differs from a Singleton approach, in that I didn’t want to force a user to extend EventDispatcher (plus I dislike getInstance()). Additionally, some of my fellow developers have noted that using the apply syntax instead of defining all the arguments with types is lazy. Since this runs through an actual EventDispatcher instance, and this class is just a proxy, I didn’t think they were necessary.

I hope someone out there finds this useful. Internally we use it quite often – and it seems to be the most reliable way to add static-access events to a class.


Update
Since I was scolded for not typing the arguments, here is an update, and a sample usage.

package {
import flash.events.EventDispatcher;
import flash.events.Event;
public class MyClass {
protected static var disp:EventDispatcher;
public static function addEventListener(p_type:String, p_listener:Function, p_useCapture:Boolean=false, p_priority:int=0, p_useWeakReference:Boolean=false):void {
if (disp == null) { disp = new EventDispatcher(); }
disp.addEventListener(p_type, p_listener, p_useCapture, p_priority, p_useWeakReference);
}
public static function removeEventListener(p_type:String, p_listener:Function, p_useCapture:Boolean=false):void {
if (disp == null) { return; }
disp.removeEventListener(p_type, p_listener, p_useCapture);
}
public static function dispatchEvent(p_event:Event):void {
if (disp == null) { return; }
disp.dispatchEvent(p_event);
}
// Public API that dispatches an event
public static function loadSomeData():void {
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
MyClass.addEventListener(Event.COMPLETE, onComplete, false, 0, true);
function onComplete(p_event:Event):void {
trace("Complete!");
}
MyClass.loadSomeData();

Free Extension: gAlign Panel

When doing design work in Flash (or laying out design elements), one of the most common panels to have open is the Align panel. It’s great for relative alignment and distribution, but we thought we could kick it up another couple notches. The result is the gAlign panel.

UPDATE

We have uploaded a new version of the gAlign panel, which works with shapes, drawing objects, and groups. Note that shapes will not work with the new drawing options.

VII. gAlign Panel

This panel has all the functionality of the Align panel (the top 3 rows), but with some much needed absolute spacing commands along the bottom. The “Distribute Spacing” commands use custom JSFL calls to distribute your elements based on the edges of the elements, rather than the registration points. For instance, refer to this image:

If you were to “Distribute” the items horizontally using Flash’s built in distribute, you would end up with the following result:

Using the new “Distribute Spacing” option in gAlign (and a spacing amount of “Auto”), you would get horizontal distribution based on the size of the elements.

Further, using the numeric spacing options, You can specify an absolute space between items. Applying a spacing of “2” to the first example would yield this result:

Download the gAlign Panel

Please feel free to let us know if you have any comments or suggestions.

There are a couple things to note.

  1. Apparently, the new align functions do not work with shapes. This is a limitation in flash.
  2. The “To Stage” toggle does not apply to the new align modes
  3. Flash treats each individual symbol position change as a seperate UNDO, instead of as a combined UNDO, since we use seperate JSFL calls to move each element.
  4. In order to align objects flush up against one another, you can distribute their spacing with a value of zero!
  5. This panel was developed for flash 7 and 8, but works in Flash 9.

Free Extension: AS3 String Utils

To continue the Extension goodness, here is an uber-handy AS3 class that we built the second we had access to AS3.

VI. AS3 String Utils

With the advent of regex in Actionscript, string methods become easier, and in some cases a lot faster. It also gave us a good exercise in AS3. This class is found in the com.chewtinfoil.utils package.
Oddly, Macromedia released a string utils class around the same time we built this, but we found that not only was there less methods, but they made no use of regex, and basically ported an AS2 version.
We have intended on releasing this one for some time, so without further ado, here it is:
Download this AS3 String Utils!
Please let us know if you find any problems, or have any other ideas for fancy string-abusing methods. See a complete API and example after the jump!
Continue reading →

Extension Melee (Part 4)

To mix things up a bit, this extension is not actually an extension, but a component. However, I think it’s fair to group it in our series of flash extensions (see part 1,2,and 3), due to its obvious usefulness 😛

VI. SimpleTabBox

The SimpleTabBox is an AS2 component we built a while back – as evidence, here is a screenshot of it in action in gProject. This is one of the components that I have always felt should have been part of the V2 component set, but for some reason, the closest Macromedia came was the release of the TabBar in one of the Devnet CDs (which was not very useful as all).
Download the Extension. Included is the component MXP, as well as the source classes, and an FLA with the skin assets.
This TabBox was designed with one thing in mind: An easy way to create a pleasant simple looking ViewStack in flash. I’m sure there are others out there, in fact Paul Ortchanian released an implementation a couple weeks ago.
I hope someone out there finds this useful. As with all of our other free extensions, feel free to let us know if you find bugs or have feature requests.
Continue reading →

Extension Melee (Part 3)

Looking over all our extensions, it is clear that the #1 thing we automate is quick access to files. gProject was initially created to give us a quick-open file listing. OpenBoundClasses and FindInLibrary also find us symbols and classes with a keystroke. Even gSearch helps us find the files or symbols we are looking for.

To round off the “Quick-Open” extensions (part 1, part 2), here are two small commands that give us two more ways to open and find files.

IV. QuickOpen

The QuickOpen panel is a proxy to your recent files. Apparently we thought click “File > Open Recent” menu wasn’t enough, so we created a popup list that you can bind to a keyboard shortcut. QuickOpen is an easy access, keyboard-accessible shortcut to the recent files. Unfortunately flash will not give focus to XUL dialogs on the Mac, so you have to click it in order to use your keyboard. Works great on PC though.

Download this extension

V. QuickOpenImport

Despite the similar name, QuickOpenImport is completely different. Often, when working on a class file (or FLA), we come across a class that we would like to open, but are unsure where it is. This extension pops up a dialog with a TextInput, and opens the class path you enter.

Download this extension

QuickOpenImport requires that you have your classes in a normal class path, since flash 7 and 8 will not tell us where it looks when compiling. Supported paths are relative to your FLA (“./”), “./classes”, “../classes”, and the flash classes directory (for components, etc). You can add paths by manually editing the JSFL, which is located in the configuration directory in the Commands folder.

That’s it for today. Look forward to more extension goodness next week!