Tcoz Tech Wire

Discoursing on trends and technologies interesting to Tim Consolazio, sole proprietor of Tcoz Tech Services, specializing in Flash/Flex/Air, iPhone, Facebook, Twitter, and related technologies.

"Technology from an indie software developer's perspective".

Thursday, December 17, 2009

Flash Builder: Spark Skinning Issue to look out for (hopefully they'll fix this)

If you're in the ActionScript world and haven't cracked open the beta of Flash Builder (the latest version of Flex Builder, just rebranded), it's time to hit the Adobe site and pull it down. There's a lot to like about it.


It ain't perfect yet though. Here's a brief post about a couple of things I've discovered that might throw you when you get started.


Spark Skinning

The new Spark components (get ready for the new s: namespace) seem to work great, and have a lot less overhead than the old mx flex ones. For instance, "groups", like s:HGroup and s:VGroup, can be used instead of "boxes", like HBox and VBox. They work the same way, but don't contain logic for scrollbars and such. This somewhat mediates the old Flex issue of nested containers impacting performance. Although you should still always be careful nesting containers, its good to know that, at least to a point, you can be a little more creative about their use without overtly damaging your app's perf. You can also do more with CSS than in the past as far as skinning, fonts, and so forth. Great stuff.


However, it's still in beta, and I stumbled across what appears to be more of an API/OOP design flaw than a bug, but nevertheless still feels like something is broken, so here it is:


When using a Spark List component, you may want to reskin the Scrollbar (let's face it, the default scrollbars are UGLY). To skin the scrollbar, you would implement a new skin class for the part of the scrollbar that you want to alter, then simply apply it to that element of the scrollbar. The easiest way to to this would be to just copy the content of the default skin class, put it in a new class, modify it to suit your needs, then apply it in place of the default one. Note that the Spark documentation says this is the way to go; you shouldn't override or extend skin classes.


However, the default scrollbar skin for the increment and decrement arrows contains an "Arrow" MXML piece. Remember, this is the SKIN class, not the implementation class. Even if I omit the skin class entirely, I would expect the app to still compile and run; a null check would avoid any errors, though you may not see a skin for the scrollbar, or a default system skin would be used; something other than the app completely breaking without any compile-time errors.


You can find the Spark skin classes in [FB Install folder]/sdks/[version]/frameworks/projects/sparkskins/src/mx/skins/spark, which is great; using them as a starting point for skinning you Spark components makes this actually very easy.


Anyway, in those default Arrow classes (the ones I'm interested in are ScrollBarUpButtonSkin, and ScrollBarDownButtonSkin), you'll see this MXML fragment:



<!-- arrow -->
<s:Path horizontalCenter="0" verticalCenter="-1" id="arrow"
data="M 3.5 0.0 L 7.0 7.0 L 0.0 7.0 L 3.5 0.0">
<s:fill>
<s:RadialGradient rotation="90" focalPointRatio="1">
<s:GradientEntry id="arrowFill1" color="0" alpha="0.65" />
<s:GradientEntry id="arrowFill2" color="0" alpha="0.8" />
</s:RadialGradient>
</s:fill>
</s:Path>


Now, I don't want that, because I'm drawing some very custom shape in place of this default arrow. So, I omit that MXML fragment, and replace it with a Graphic object, in which I use the new drawing MXML stuff to create a new arrow.



<s:Graphic width="25" height="20">
<s:Path data="M 0 0
L 25 0
L 25 10
L 12.5 20
L 0 10
L 0 0" >

<s:stroke>
<s:SolidColorStroke color="0x29a094"/>
</s:stroke>

<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xFFFFFF" alpha="1"/>
<s:GradientEntry color="0x7ac8c5" alpha="1"/>
</s:LinearGradient>
</s:fill>

</s:Path>
</s:Graphic>


After making the new class with the Graphic element instead of the old "arrow" drawing path one, I applied it to my Spark List component and compiled; new errors. I ran the program though, and it crashed right away. The error was that the "arrow" property could not be found, and there was no default value, etc. So, out of curiosity (and the desire to get the app running), I just added a public var, "arrow" : Object, and again compiled without errors. Running it though caused another error, and then another, because "arrowFill1" and "arrowFill2" were not found, no default value, etc.


So, I had to add these three public vars to my custom class to get the app to run.



// don't remove these, they are placeholders for the wonky "arrow" mxml that isn't needed here.
public var arrow : Object = { };
public var arrowFill1 : uint = 0;
public var arrowFill2 : uint = 0;


After that it worked.


To me, this is broken; as long as the skin class is properly made, it shouldn't need to contain ANYTHING in order to run properly, as long as any necessary interfaces are implemented (a well built API should be interface based). Implementation of functional objects should not be a concern of the skin class. But it is; you have to put in those dummy properties to get this to work.


I circulated this find, and the consensus seemed to be that yes, this should be fixed; there's no reason a required visual object should be in a skin class, circumventing compile time errors and crashing the entire app when it tries to instantiate a skin for a scrollbar. Evidently, more hacking away found that this is the case in a number of Spark skins.


Insurmountable? Nah, just add the public properties to satisfy the Spark parent component demand for whatever it's looking for. But it's wonky and, as far as the consensus of the people I referred the error to, should be addressed by Adobe before the product is released, for the sake of elegance if nothing else.


As always, thanks for visiting.

Labels: , , , , , ,

Tuesday, June 2, 2009

Adobe Flash Builder (formerly Flex), first looks: Compatibility with older Flex, different namespaces...other immediate differences?

Adobe Flash Builder (formerly Flex), first look: Compatibility with older Flex, different namespaces...any other immediate differences?

Yesterday, Adobe announced the general availability of Flash Builder 4 Premium Beta, and Flash Catalyst, which I may or may not discuss some other day. The coder tool is Flash Builder, and that's my primary interest by far, though Catalyst does look interesting...and possibly headache inducing, as it's a way for non-coders to generate code without actually understanding it. Historically, that's always been a mess.

This article focuses on my initial experiments with Flash Builder, which is the new Flex, rebranded. I installed it on my only non-work machine, which is a Windows XP box. Apologies to the Mac loyalists.

My first concern is, can I use old Flex projects in the new Flash Builder? This is primary to me because, if you went through the whole wrestling match of Eclipse Flex Plugin projects vs. Flex Builder Projects vs. Flash projects (which really don't exist, it's just a folder with relatively located assets), and of course the whole CS3 to CS4 upgrades with subsequent months of, "I don't have Flash CS4 can you export to CS3...I don't have Photoshop CS4 can you downgrade the .psd," you know that it's EXTREMLY important that you be able to import old projects, and export new ones in the older formats. This still makes the whole SVN thing a mess if people are using different versions, but that's more a team workflow/standards thing; a team should agree on a version and all upgrade at the same time.

Anyway, I found some issues. I'm sure I'll find more, and of course it's possible there's more for me to learn about the new tool and V4 SDK, but this is where I'm at onDay 1.

On launch, the new Flash Builder looks pretty much identical to the old one. Screenshot below.







Right off the bat, when I go to the File menu, there it is: "Import Flex Project" and "Export Flex Project (FXP)" menu selections. Alrighty, let's try the import process on a fairly big Flex project, the codebase for my PlanetSudoku game.

After selecting the project folder (which I just dragged onto my Windows desktop from my Mac Flex Builder 3 workspace), a dialog popped up asking me what Flex SDK I wanted to use. The default is Flex 4.0, but I could select any other SDK I had installed (it appears to also install 3.4 for you, which is nice). Let's be daring: I'll compile it with 4.0.







Continuing on, I get the warning, "If you convert, you won't be able to use this project in older versions of Flash Builder...". Hmm, ok, I guess I could always just use the Export feature if I needed to...more on that later.

Note: If you are getting the idea into your head that you can start using the Beta full-time now because you can import and export projects, that is a BAD idea. BAD. It's a beta product, you should NOT use it for production work. And as you read on, you'll see how bad it can be.

Without trying to run it, the import worked, here's a shot of the project structure. Good 'ol bin-debug is still there, html-template, my asset folders, my sounds, all the structure looks like it imported cleanly. Note that "Flex 4.0" is now it's own library category, and there looks like there's some new things in there. That'll have to wait for another blog post.







Ok, no errors, let's open an ActionScript file and look at the code editor. Here's a nice surprise; all .as files are nodes, which when expanded, show the structured outline of the file, just like the "Outline" window. I guess that window is sort of redundant now, though it does have sorting options and such.







At first glance, things look pretty much the same in the code editor window, though there does seem to be some new icons to assist in scanning through the lists of auto complete selections, like below (notice the "Native" icon):







Ok, enough dinking around, let's run this thang...AHAH! When I go to the Run button, I see a new choice, something that appeals to the "enterprise" in me...Execute Flex Unit Tests! Clearly evidence that Adobe is getting more serious about the more serious coder. Gotta look that one up in the help files ("Help" appears identical to old Flex help FYI). More :







Help says the following about the FlexUnit Test Environment:

The FlexUnit test environment allows you to generate and edit repeatable tests that can be run from scripts or directly within Flash Builder. From Flash Builder, you can do the following:

Create unit test cases and unit test suites

Flash Builder wizards guide you through the creation of test cases and test suites, generating stub code for the tests.

Run the test cases and test suites

You can run test cases and test suites various ways from within Flash Builder or outside the Flash Builder environment. The results of the tests are displayed in a test application. Flash Builder opens a Flex Unit Results View for analysis of the test run.

Navigate to source code from the Flex Unit Results View

In the Test Results panel, double-click a test to open the test implementation.

The Test Failure Details panel lists the source and line number of the failure. If the listed source is in the current workspace, double-click the source to go directly to the failure.


Ok, that's definitely another blog article in the making. There's unit testing frameworks out there for Flex that I've seen, but integrated? That's significant.

So, back to running the project...ARGH. A browser window pops up, but then an ActionScript error window comes up with the following message:

"VerifyError: Error #1014: Class IAutomationObject could not be found."

Ok, I know it's probably fixable using SDK 4, however, what I'm going to try is deleting the entire project, and reimporting it using the 3.4 SDK (which is the only other one available in the dropdown; I might actually not have another Flex SDK installed on this machine, so it's nice they seem to install 3.4 for you).

First thing I notice; the Flex 4 folder is now Flex 3.4, and some of those "new things" are gone. Ok, so the Flex 4 SDK is quite a bit different than 3.4, that's good to know.

No errors, let's try running it...SUCCESS! The project ran just fine.

So, Compatibility Lesson 1: DON'T USE THE Flex 4 SDK FOR 3.x SDK PROJECTS. At least, not unless you're willing to wrestle with differences to use the newer one. Predictable, but now confirmed.

Now, let's try a Debug run. No surprises. Seems to work just like the old one.

Time to try it the other way around. I'll create a "Hello World" project in Flash Builder 4, using the V4 SDK, export it, and try to load it into Flex Builder 3.

When creating the new project, I notice it's not a "Flash Builder" project, it's still a "Flex Project." All the choices look identical to Flex 3.The project created as expected, but I noticed one thing: The top level MXML file still contains the Application element, but it looks different (note the "s" and "fx" namespace declarations):


<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768">

</s:Application>


Application now falls under this namespace declaration: xmlns:s="library://ns.adobe.com/flex/spark". If you recall from the screenshot of the Flex 4 folder above, there is a .swc called "sparkskins". Hmm. Drastic changes afoot?

Aside from that, the dev tasks look the same. I'll drag 'n drop a button and a label, and set up the click event handler to populate label with "Hello Flash Builder Export Test!".

Bonk! When I went to type <mx:Script>, like I usually would, it didn't get recognized: no CDATA tags and closing </mx:Script> tags got generated. After a little dinking by looking at the declared namespaces, I found the Script tag in the fx namespace. This has the desired result...but oh jeezus. I'm going to have to unlearn some pretty basic things it seems.

The test code looks like this, and worked exactly as expected. Interestingly, no more weird Flex green background, it was just plain white (thank you Adobe...wtf was with that grey/green background anyway). No screenshot for this, just imagine a white background, with a Flex (erm..."Flash Builder") button, which when clicked, populates an mx:label (erm..."s:label"):


<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768">

<fx:Script>
<![CDATA[
private function onClick ( event : MouseEvent ) : void
{
lbl.text = "Hello Flash Builder Export Test";
}
]]>
</fx:Script>


<s:Button x="192" y="28" label="Button" click="onClick ( event )"/>
<mx:Label id="lbl" x="96" y="86" text="Label" width="288"/>

</s:Application>



Export time. I'll use the File...Export Flex Project (FXP) option. This creates a Flex Project archive, which I should be able to import nicely. Here goes...

...not even close. Again, undoubtedly because I created the project using the Flex 4 SDK. Meh, I was curious, but this is exactly what I expected. so I'll recreate the project using the 3.4 version and re-export it. In the new 3.4 SDK project, I notice that the "mx" namespace is back, everything looks kosher, just change the "fx" and "s" namespaces to "mx", and the code ported over fine.

Over in the Flex Builder 3 UI...import FXP...BLEARGH! It didn't work. This simple little project, when imported into Flex Builder 3, failed. Wouldn't build, nothing in bin-debug, nada. So it seems, Lesson 2: at least for now, DON'T BUILD PROJECTS IN FLASH BUILDER AND EXPECT FLEX USERS TO BE ABLE TO EASILY IMPORT THEM!

Sure, as always, there's things I probably don't know, but I appear to be following the guidelines pretty straight. Time to RTFM, look at the help docs more carefully, etc.

Anyway, that's a long enough post. Thanks for coming along on my first tour of Adobe's new Flash Builder.

Labels: , , , , , , , ,