Flash Catalyst – The Missing Visual Editor

As a new era in RIAs is coming up, one of the largest questions for developers and designers is, “What role will Flash Catalyst play in RIA development?”
My opinion is that Flash Catalyst will find its place into the hearts and minds of many designers that are wanting to layout new Flex applications before they go to full development, but as a developer I see it as the missing visual editor for Flash Builder.
If you have spent any time laying out spark skins I am sure that you would have found spark skinning to be a fun process, but very labor-some. As we were developing the BugQuash app I spent the time initially to make each and every skin 100% “by hand”, and after a while I gave up and tried to find an easier process to making the many skins provided by Dimi.
The Missing Visual Editor
If you have used Flash Builder and worked with the design view you would have noticed you can edit some of the properties of a spark skin, but you would have found it quite impossible to create or really change the skin. So now this is where Flash Catalyst works into my current workflow, I can truly edit and create skins within Flash Catalyst and get the code to copy off into my Flash Projects.
Making A New Custom Button
Starting from scratch is just as easy as creating a new Flash Catalyst Project. We aren’t going to making anything crazy, just start with a button.
Drag and Drop a Button onto the stage.
And select the state that you want to edit, and the artwork element…
You will notice lots of options for drawing and editing the components you are trying to design.
Flash Catalyst Toolbar

Flash Catalyst Properties Panel
As I make adjustments to the button I can start wherever, but I am going to start with the base shape. In this example I will play with the triangle and go through the different states of the button and make changes to the shape on all states.
Don’t forget that by right-clicking on specific elements/groups you can select to share across states so that you don’t have to do lots of coping/pasting.

With the Triangle Base Shape
In Flash Catalyst you can select shapes and different objects and adjust the alignment, arrangement, share elements across states, and play with the grouping of the objects. Very helpful for making complex objects.
Expert Note: As a Flex Developer you should be really worried about the number children objects have because that effects the performance of your application. On top of that, if you have many containers this hurts performance because each time the component needs a redraw all the children have to be remeausured and relayed out. But with Flex 4, all these children elements that you add to groups are actually all flattened together into one display object, highly improving the layout and drawing process – unless you add a rotation to the specific element which designates it to its own display object.

Display Object Right-Click Menu
So far you may have thought that the changes we’ve made have been minor, compared to an entire application they are, but these few changes have actually made a lot of code and different calculations that we haven’t had to – which is GREAT!. To switch and see the generated code we just go up to the design/code view dropdown (shown below) and change to the code view.

Design/Code Dropdown
We can now see the generated code and even the currently selected element’s code being selected in code view.
And the code…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | <?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" alpha.disabled="0.5"> <fx:Metadata><![CDATA[ [HostComponent("spark.components.Button")] ]]></fx:Metadata> <s:states> <s:State name="up"/> <s:State name="over"/> <s:State name="down"/> <s:State name="disabled"/> </s:states> <s:Path data="M 77.95 135.00 L 0.01 0.00 155.89 -0.01 Z " height="135" id="path3" includeIn="disabled" width="155.85" x="0.49" y="0.51"> <s:stroke> <s:SolidColorStroke caps="none" color="0x5380D0" joints="miter" miterLimit="4" weight="1"/> </s:stroke> <s:fill> <s:SolidColor color="0xFFFFFF"/> </s:fill> </s:Path> <s:Path data="M 77.95 135.00 L 0.01 0.00 155.89 -0.01 Z " height="135" id="path2" includeIn="down" width="155.85" x="0.49" y="0.51"> <s:stroke> <s:SolidColorStroke caps="none" color="0x5380D0" joints="miter" miterLimit="4" weight="1"/> </s:stroke> <s:fill> <s:SolidColor color="0xFFFFFF"/> </s:fill> </s:Path> <s:Path data="M 77.95 135.00 L 0.01 0.00 155.89 -0.01 Z " height="135" id="path0" includeIn="over" width="155.85" x="0.49" y="0.51"> <s:stroke> <s:SolidColorStroke caps="none" color="0x5380D0" joints="miter" miterLimit="4" weight="1"/> </s:stroke> <s:fill> <s:SolidColor color="0xFFFFFF"/> </s:fill> </s:Path> <s:Rect height="1" id="rect2" includeIn="down" width="66" x="45" y="43"> <s:fill> <s:SolidColor alpha="0.25" color="0x5380D0"/> </s:fill> </s:Rect> <s:Rect height="1" id="rect3" includeIn="down" width="68" x="44" y="44"> <s:fill> <s:SolidColor alpha="0.07" color="0x5380D0"/> </s:fill> </s:Rect> <s:Rect height="20" id="rect4" includeIn="down" width="1" x="44" y="44"> <s:fill> <s:SolidColor alpha="0.07" color="0x5380D0"/> </s:fill> </s:Rect> <s:Rect height="20" id="rect5" includeIn="down" width="1" x="111" y="44"> <s:fill> <s:SolidColor alpha="0.07" color="0x5380D0"/> </s:fill> </s:Rect> <s:Path data="M 77.95 135.00 L 0.01 0.00 155.89 -0.01 Z " height="135" id="path1" includeIn="up" width="155.85" x="0.5" y="0.5"> <s:stroke> <s:SolidColorStroke caps="none" color="0x5380D0" joints="miter" miterLimit="4" weight="1"/> </s:stroke> <s:fill> <s:SolidColor color="0xFFFFFF"/> </s:fill> </s:Path> <s:RichText color="0x2b4381" id="labelDisplay" minWidth="69" text="(Label)" textAlign="center" x="44" y="48"></s:RichText> <s:transitions> <s:Transition fromState="over" toState="up" autoReverse="true"> <s:Parallel> <s:Parallel target="{path0}"> <s:Fade duration="0"/> </s:Parallel> <s:Parallel target="{path1}"> <s:Fade duration="0"/> </s:Parallel> </s:Parallel> </s:Transition> </s:transitions> </s:Skin> |
Lots of code that you would have written anyways, taken care of for you by Flash Catalyst. I know that many developers like to put down generated code and defend their job security by saying that all other code stinks, but if you have written a skin file the file you would probably agree that most skin files closely resemble the generated code. Once you start adding groups and other design parts your hand written skin will be almost exactly the same as the generated code – so make your life easy and use Flash Catalyst.
My favorite thing is the generated Path code. You’ll notice I didn’t spend a second calculating all the different X and Y coordinates for the triangle paths to make it look as desired. A big time saver.
Using the Properties Panel
Now with our very boring and simple triangle we can go to the properties panel and just do some point and click changes to our different states. Again, more code generating options that would have resulted in lots of redundant typing that is simplified by Flash Catalyst.
By just making some simple changes to the shape (the fill and stroke) colors, we get a much better button to work with. I’ve also grouped my label and path (the triangle) to make the shape simpler. If I want to select a specific element in the group I can use the layers panel.
Continuing ToPretty Things Up
This next step is again not very impressive or difficult with Flash Catalyst, but I am going to spend a second to add additional filters to the button before adding any transitions.
And the nice clean generated code…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" alpha.disabled="0.5" xmlns:d="http://ns.adobe.com/fxg/2008/dt"> <fx:Metadata><![CDATA[ [HostComponent("spark.components.Button")] ]]></fx:Metadata> <s:states> <s:State name="up"/> <s:State name="over"/> <s:State name="down"/> <s:State name="disabled"/> </s:states> <s:Group x="0" y="0" id="group1"> <s:filters> <s:DropShadowFilter includeIn="up" blurX="4.0" hideObject="false" distance="4.0" blurY="4.0" inner="false" color="0x000000" strength="1" alpha="1.0" quality="2" knockout="false" angle="45.0"/> <s:DropShadowFilter includeIn="over" blurX="4.0" hideObject="false" distance="4.0" blurY="4.0" inner="false" color="0x000000" strength="1" alpha="1.0" quality="2" knockout="false" angle="45.0"/> <s:DropShadowFilter includeIn="down" blurX="4.0" hideObject="false" distance="4.0" blurY="4.0" inner="false" color="0x000000" strength="1" alpha="1.0" quality="2" knockout="false" angle="45.0"/> <s:DropShadowFilter includeIn="disabled" blurX="4.0" hideObject="false" distance="4.0" blurY="4.0" inner="false" color="0x000000" strength="1" alpha="1.0" quality="2" knockout="false" angle="45.0"/> </s:filters> <s:Path data="M 77.95 135.00 L 0.01 0.00 155.89 -0.01 Z " height="135" id="path1" width="155.85" x="0.5" y="0.5" y.down="0.51" x.down="0.49"> <s:stroke> <s:LinearGradientStroke caps="none" joints="miter" miterLimit="4" rotation="90" weight="1"> <s:GradientEntry alpha="1.0" color="#2b4381" ratio="0" color.over="#ffffff" alpha.over="1.0"/> <s:GradientEntry alpha="1.0" color="#009cff" ratio="1"/> </s:LinearGradientStroke> </s:stroke> <s:fill> <s:LinearGradient rotation="51.34"> <s:GradientEntry alpha="1.0" color="#002fd1" ratio="0" color.over="#cdcbff" alpha.over="1.0"/> <s:GradientEntry alpha="1.0" color="#cdcbff" ratio="1" color.over="#002fd1" alpha.over="1.0" ratio.over="0.7019607843137254"/> </s:LinearGradient> </s:fill> <s:stroke.down> <s:SolidColorStroke weight="1" caps="none" miterLimit="4" joints="miter" color="#402ba7"/> </s:stroke.down> <s:fill.down> <s:SolidColor color="#5380d0"/> </s:fill.down> </s:Path> <s:RichText color="#ffffff" fontFamily="Arial Bold" id="labelDisplay" minWidth="69" text="(Label)" textAlign="center" x="44" y="48"></s:RichText> </s:Group> <s:transitions> <s:Transition fromState="up" toState="over" autoReverse="true"> <s:Parallel> </s:Parallel> </s:Transition> </s:transitions> </s:Skin> |
Transitions
Currently the transition options that I would want for this component aren’t available, but I am sure they will be soon. Typically though this would be the time for you to add the transitions to your component and I would want to add a graphical shift to the colors – again, not available at this time.
Actions
Other things that you can set in Flash Catalyst are actions based on events from the components you’ve used. However since we’re not trying to make an application mockup we don’t really need to worry about what happens when the button is clicked, because that will be set in the application itself.
Publish
If you were to be taking in the code to your application you would be done now. But just for the fun of it I’m going to publish it so you can see the final button.

Flash Catalyst Publish Screen
The Application Ready Button










[...] This post was mentioned on Twitter by Joseph Burchett, FlashAbility. FlashAbility said: RT Flash Catalyst- The missing visual editor- http://twurl.nl/stnxuu #flash #flex: Flash Catalyst- The missin.. http://bit.ly/xJbn8 [...]
Social comments and analytics for this post…
This post was mentioned on Twitter by FlashAbility: RT Flash Catalyst- The missing visual editor- http://twurl.nl/stnxuu #flash #flex: Flash Catalyst- The missin.. http://bit.ly/xJbn8…
I’m also waiting for Flash Catalyst.
And thanks to the author for detailed instructions!
Nice write up Jon!