Showing posts with label FFC's. Show all posts
Showing posts with label FFC's. Show all posts

Wednesday, August 01, 2007

FFC : Button - Limitations

After making good progress developing my own LinkButton Fireworks Flex Component (FFC) I was keen to take this a bit further by extending one of the existing FFC's. The natural progression from the LinkButton was to take a look at the Button component. If you installed the Flex Style Explorer you can quickly have a play with the available style options for the Button. There are a number of styles that the LinkButton and Button share. But you'll quickly notice one big difference. The Button has a background (all states) with a gradient and you can change the gradients colors and alpha. The fill colors are controlled using the fillColors array. It looks something like this:

fillColors: ['#FFFFFF','#CCCCCC','#FFFFFF','#EEEEEE'];

The first two values represent the colors for the up states top and bottom colors respectively. The second two values represent the colors for the over states top and bottom colors respectively. The down state is controlled by the themeColor. It turns out to be pretty easy to display changes to the fillColors values by setting the fills gradient.nodes color. The nodes is an array with the Button background having two nodes. You would set the color of one node like this :

var vals   = Widget.elem.customData["currentValues"];
bg_obj = Widget.GetObjectByName("up_fill");
bg_obj.pathAttributes.fill.gradient.nodes[0].color = vals[8].value;

Setting the fillAlphas is a similar process except that you use the gradient.opacityNodes color. There is one crucial difference and that is the addition of an alpha component to the color value. For example, '#FFFFFFFF' is a white opacityNode set to 1.0 (no transperancy); '#FFFFFF00' is a white opacityNode set to 0.0 (full transperancy). The tricky bit here is working out the hex values for the alpha component. Perhaps there is a neat line of javascript that someone could suggest to sort this out. But in the end I wrote a function with a series of conditionals to set values at 0.05 increments. A bit awkward but effective enough for my needs.

This was all good. But as I was working through these issues I finally came to an impasse. As you can see the fillColors property is an array. That's alright we can have an array. But to my knowledge we can't have an array with a color picker for each index. That means hand typing the colors and I was really aiming for better. The other option is to use four values and to combine them for MXML output. This may be an option and I'll probably explore this option. But this got me thinking. What would be great is if you could develop a Flash panel for individual components that shows inside the Symbol Properties and allows you to set properties using a GUI (ie. like the Flex Style Explorer). Ideally this swf just needs to exist alongside the graphic and jsf files for it to be used. So if Button.swf existed in your custom component folder it would become the components editor.

Saturday, July 28, 2007

"Geeking Out" On Fireworks Flex Components

I've been a regular reader of Alan Musselman's blog for as long as I can remember. If you are at all interested in using Fireworks then Alan is the man to read. Even if it's only to discover all the other great blogs he mentions. So I was very excited to read his blog today and discover his post was about this blog. Specifically his post relates to my ongoing experiements with building Fireworks Flex Components (FFC's) with links to four of my posts on this topic. Below is the complete list of posts on FFC's :

Saturday, July 14, 2007

FFC : LinkButton - Tidying Up

This is my third post looking at creating a LinkButton Fireworks Flex Component (FFC). In the first post we looked at using a state property to manage the appearance for different states of the FFC within Fireworks. This state property created a problem with the exported MXML by introducing an invalid property so in the second post we talked about using flexClassDefinition to get more control over the exported MXML. In this post we'll look at some of the small details that we missed in those posts.

Firstly, let's look at adding a property to manage if the LinkButton is enabled. This property is included in the default FFC's and I'm aiming to maintain consistency with those as much as possible. We actually need two properties; enabled (a Boolean) and disabledColor (a Color). The disabledColor effects the text color when the LinkButton is disabled. All that's required to make this work is the addition of an additional if statement within applyCurrentValues :

if(enabled)
{
switch (state)
{
//states managed here
}
}
else
{
label_obj.pathAttributes.fillColor = values[13].value;
bg_obj.visible = false;
}

The second missing detail relates to a group of three properties that are relatively easy to implement ; fontWeight, fontStyle, textDecoration. Each of these properties have two potential states (which vary for each). So the best way to handle this in the properties is with a ComboBox :

values.push({ name:"fontWeight", type:"ComboBox", value:"bold,normal,bold" });
values.push({ name:"fontStyle", type:"ComboBox", value:"normal,normal,italic" });
values.push({ name:"textDecoration",type:"ComboBox", value:"normal,normal,underline" });

This creates a slight complication in applyCurrentValues because in Fireworks each of these settings is actually a Boolean so we need to do a simple if else statement for each property :

if(values[9].value.split(",")[0] == "bold")
{
label_obj.bold = true;
}
else
{
label_obj.bold = false;
}

if(values[10].value.split(",")[0] == "italic")
{
label_obj.italic = true;
}
else
{
label_obj.italic = false;
}

if(values[11].value.split(",")[0] == "underline")
{
label_obj.underline = true;
}
else
{
label_obj.underline = false;
}

Adding these also creates a problem in the export. Because it outputs all the options to the MXML rather than just the selected one. I could make them all Text but then you'd need to know the correct value to type in. Which could lead to all sorts of problems. As is all you need to do is to remove the unwanted options from the MXML. I'm keen to fix this but I haven't found an answer as yet. With some luck a kind reader will emerge with the solution.

There are four other styles that could be added to our LinkButton FFC ; cornerRadius, paddingLeft, paddingRight, letterSpacing. They could be easily added to the properties list. But I've yet to find a way to update the FFC to display these styles. Everything else we've added is able to be visualised and I don't see any value in having the styles included if they can't be displayed. The whole point is to be able to create a document that can be used to create a design and to output a working Flex file. So for now I've left these styles out until I can find a way to get them working.

If you want to use my LinkButton FFC or use the files as the basis for your own FFC's or you want to experiment with the missing details you can get the files here.

Thursday, July 12, 2007

FFC : :LinkButton (flexClassDefinition)

In my last post we talked about creating a LinkButton Fireworks Flex Component (FFC). By the time we finished we had a component that could update and export the LinkButton's different states. We could also control the label, font and fontSize. As you may remember there was a problem in the exported MXML. There isn't a state property for LinkButton and consequently Flex Builder correctly flagged an error.

We can get more control over what is exported to MXML by using the flexClassDefinition. The flexClassDefinition is an object with some useful properties that can be added to customData. The basics looks like this:

var definitionObject = new Object();
Widget.elem.customData["flexClassDefinition"] = definitionObject;

You won't see this defined in the default FFC's (e.g Button) as this is handled by the exporter. But for our custom components this mechanism is needed. I'm not going to talk about all the available properties (because there is an article that does a much better job than I ever will) only those we need. Let's start by removing 'state' from the exported MXML. To do this we define the attributes we wanted exported:

definitionObject.defaultProperties = ["id","x", "y", "width", "height"];
definitionObject.attributeProperties = ["label", "enabled"];

The defaultProperties is an array of attributes that we haven't defined as properties and that we want to have included. The array can also include; alpha, source and styleName. By not including these within defaultProperties they won't be included in the export. If one of the included defaultProperties isn't required (for example if we don't change the FFC's opacity it's alpha attribute isn't required) it isn't exported.

The attributeProperties is an array of the properties that we've defined that we want included. By not including 'state' in this array then 'state' isn't included in the exported attributes. You'll notice I've kept this list short and consequently none of the style properties would be exported. The reason is that I actually want them defined as a style. In fact ideally I'd like to have one style defined for all LinkButtons if they look the same and to use custom styles if they are different. I want the same styling intelligence we get using Text to create Labels (see FFC : Label for more on this). We can get this exact behaviour by defining styleProperties :

definitionObject.styleProperties = ["color","textRollOverColor",
"textSelectedColor","rollOverColor",
"selectionColor","fontFamily",
"fontSize","disabledColor"];

Defining styleProperties like this earns us the following style definition in the exported MXML :

<mx:Style>
LinkButton {
disabledColor:#AAB3B3;
fontSize:11;
fontFamily:Verdana;
selectionColor:#7FCDFE;
rollOverColor:#AADEFF;
textSelectedColor:#2B333C;
textRollOverColor:#2B333C;
color:#0B333C;
}
</mx:Style>

That brings us pretty close to a fully functional LinkButton FFC. There are still a few things that can be added and a few problems to be solved. But let's talk about them next time. Until then you might want to take a look at the source files.

Wednesday, July 11, 2007

FFC : LinkButton (Managing State)

A little while ago I wrote a few posts relating to creating a simple HRule Fireworks Flex Component (FFC). I chose the HRule because it wasn't interactive and hence relatively simple to implement. But now I'd like to move on and do something a little bit more interactive and to tackle some of the issues involved. Looking around I settled on the LinkButton. LinkButtons display a label with no background in the normal state. On rollover the background is displayed and the label changes color. On mouseDown the backround color changes and the label color could change (the default is that the rollover and selected label colors are the same).

Looking at the Button component from the Flex Components you'll notice a State property with three options ; Up, Over and Down. In the Button FFC changing the textRolloverColor and then selecting the Over state you'll see the FFC update to display the new textRolloverColor. This State property allows us to preview the style changes that relate to different states of an interactive component. Adding this State property to the setDefaultValues function is our first job when creating an interactive component. It looks like this :

values.push({ name:"State",type:"ComboBox", value:"Up,Up,Over,Down" });

Within applyCurrentValues we'll need to get the current selection of this property:

var state   = values[0].value.split(",")[0];

Then use the value of state to decide what values to apply. Before doing that lets take a look at the structure of LinkButton.graphic.png. Like the HRule it's very simple. There is a text field named 'label' and a rectangle named 'bg'. For each of the selected states we'll need to update the color of 'label' and the color and visibility of 'bg'. To do this we need to define 5 properties within setDefaultValues ;

values.push({ name:"color", type:"color", value:"#0B333C" });
values.push({ name:"textRollOverColor", type:"color", value:"#2B333C" });
values.push({ name:"textSelectedColor", type:"color", value:"#2B333C" });
values.push({ name:"rollOverColor", type:"color", value:"#AADEFF" });
values.push({ name:"selectionColor", type:"color", value:"#7FCDFE" });

Here's the code from applyCurrentValues that uses the current state to set these values;

var state   = values[0].value.split(",")[0];

var label_obj = Widget.GetObjectByName("label");
var bg_obj = Widget.GetObjectByName("bg");

switch (state)
{
case "Up" :
label_obj.pathAttributes.fillColor = values[2].value;
bg_obj.visible = false;
break;
case "Over":
label_obj.pathAttributes.fillColor = values[3].value;
bg_obj.pathAttributes.fillColor = values[5].value;
bg_obj.visible = true;
break;
case "Down":
label_obj.pathAttributes.fillColor = values[4].value;
bg_obj.pathAttributes.fillColor = values[6].value;
bg_obj.visible = true;
break;
}

As you probably spotted the tricky bit is getting the value of state. But this line is copied straight out of the Button component so the only credit I get is for being smart enough to look at those components. The rest is a matter of changing the fillColor for the 'label' and 'bg' to the relevant colors and setting the visible property of 'bg'. Set visible to false for the 'Up' state and true for the others.

There are a few other relevant properties/styles we can easily change. The simplest properties are the label property (controls the text visible on the LinkButton), font and fontSize :

//setDefaultValues after state
values.push({ name:"label",type:"Text",value:"Button"});
//setDefaultValues after selectionColor
values.push({ name:"fontFamily", type:"font", value:"Verdana" });
values.push({ name:"fontSize", type:"Text", value:"11" });

//applyCurrentValues after state switch statement
label_obj.textChars = values[1].value;
label_obj.font = values[7].value;
label_obj.fontsize = Number(values[8].value);

All this works nicely within Fireworks but there is a problem that you may have spotted. When we export to MXML Flex Builder will display an error because 'state' is not a valid attribute for the LinkButton (all Fireworks properties are added as attributes). For now we can simply remove the state attribute. But to fix the export we need to talk about "flexClassDefinition". Let's save that till the next post. In the meantime you can look ahead by downloading the source files.

Saturday, July 07, 2007

Fireworks Flex Components : Label

One thing I noticed the other week and have only just had a chance to invesitgate further is that Fireworks doesn't have a Label or a Text component. There is a good reason for this; it doesn't need them. If I draw a rectangle path on the stage and export it the rectangle is defined as an Image and a gif is exported with the MXML file to fill that position. But try placing a piece of text onto the stage and then exporting to MXML. Fireworks will define the Text within MXML as a Label. It will also define a Label style to define the appearance of the Label. Even more interesting if you add a second seperate piece of Text with some difference in appearance it will define two custom styles to define the appearance of the two Labels and add the styleName attribute to the Label. There is one final piece of intelligence that ensures the Fireworks to Flex workflow is spot on. Add a multi-line piece of Text to the stage and export. What you'll notice is that the multi-line text is exported as a Text component and that a Text style is defined.

This capability to appropriately export Text into mxml isn't mentioned in any documentation I can find and isn't immediately obvious when you look at the Flex Components. But it certainly is very useful once you know about it.

Friday, July 06, 2007

Fireworks : Flex Style Explorer

A while ago I saw this article on Flex styling in Fireworks CS3. I didn't write about it at the time because I didn't have access to CS3 and couldn't really test things out. But in my continuing search for the best way to integrate Fireworks into the Flex development workflow I've just taken another look. The real gem in this article is the Flex Styles Explorer. I've been using the online version of this tool from the day it first appeared and I use it often. It's a genuine time saver for styling Flex components. The Fireworks version of the tool gives easy access to the tool offline as well as allowing you to copy the generated css for use in Flex. It doesn't apply the styles to the Fireworks Flex Components so you won't be able to completely reproduce the design in Fireworks. But it provides a path for getting it quickly into Flex and anything that makes life easier is a good thing to me.

Monday, July 02, 2007

Fireworks Flex Components : Extended

In a recent post I was looking at the steps required to create a simple HRule FFC (Fireworks Flex Component). You may remember that I included a property for defining the strokeWidth style but I didn't go so far as to actually get the FFC to update it's appearance because I wanted to keep the post simple. Over the last couple of days I've been working towards implementing this last element. But it turned out to be a little more difficult than I expected and required a few changes to my original FFC to make it work. The aim of this post is to look at these changes and what was required to make this work.

Firstly, let me talk about the reason I had trouble finding what in the end was quite a simple solution. With Fireworks javascript the best way to find out whats going on is to select the step you are interested in from the history panel and then select "copy steps" from the panels menu. This copies the relevant javascript to the clipboard. But that doesn't help us with our FFC's because the 'Symbol Properties' panel talks to the FFC using the Widget object. This interface works somewhat differently from the main API. The second reason this proved difficult is that none of the existing FFC's have an example of changing an object size within the FFC. In the end I found myself hunting through "Adobe Fireworks CS3 - Extending Fireworks" to find the answers I need (search for Widget and pathAttributes).

So firstly lets take a look at what changes we need to make to the HRule.graphic file. It's quite simple; we just need to replace our two paths with lines and then rename them as 'line' and 'shadow'. You'll then need to confirm they are correctly positioned. For some odd reason I found I needed to place the shadow 2 pixels below the line. These were the only changes I needed to make to the graphic.

Next open up the HRule.jsf file. The first change I made was within 'setDefaultValues' where we change the strokeWidth properties type from being a number to "Text". I'm not sure why this was necessary but a couple of issues disappeared when I did. Most of the real changes occured in 'applyCurrentValues' so let's have a look at the whole function :

function applyCurrentValues()
{
var values = Widget.elem.customData["currentValues"];
var w = Number(values[1].value);

var line_obj = Widget.GetObjectByName("line");

line_obj.pathAttributes.brushColor = values[0].value;
line_obj.pathAttributes.brush.diameter = w;

var shadow_obj = Widget.GetObjectByName("shadow");

shadow_obj.pathAttributes.brushColor = values[2].value;
shadow_obj.pathAttributes.brush.diameter = w;
}

The first line remains the same, but note the second line where we pick up the value for strokeWidth and convert it to a number. Now there are two blocks of three lines one for 'line' and one for 'shadow'. Both blocks do exactly the same thing but to a different path. The first line of each stores a reference to the object within a variable. This saves us from writing Widget.GetObjectByName("objectName") on the next two lines of eaach block. Those two lines are probably self explanatory but let's take a quick look. Both use 'pathAttributes' to change properties of the path. The first refernces brushColor to change the color of the paths stroke. For 'line' it gets changed to strokeColor. For 'shadow' it gets changed to the shadowColor. On the second line of each we set the brush.diameter to the strokeWidth.

That's it! You'll need to reload the "Common Symbols" panel and then drag the HRule component onto the stage. But now any changes we make in 'Symbol Properties' will be reflected within Fireworks as well as being exported into the MXML. From here we can very easily make a VRule FFC simply by saving HRule.graphic.png as VRule.graphic.png and rotating the lines. Then saving HRule.jsf as VRule.jsf and changing HRule to VRule on the first line of 'setDefaultValues'. Too easy. There's still quite a few things to work out before we could improve the existing FFC's or to make a full set. But with what we know now we could make a fairly complete set.

Thursday, June 28, 2007

Fireworks CS3 : Creating Flex Symbols

Fireworks CS3 added the ability to export an MXML layout from your design for use with Flex. To assist this it includes a selection of common Flex components. These components are stored in Windows > Common Libraries > Flex Components. By adding the Button to your design and exporting to MXML you will find yourself with the appropriate MXML for a basic application with a Button. This is great as far asit goes. The Flex Components within Fireworks represent a small subset of the available Flex components. You have very limited options for styling these components and everything will be positioned absolutely. The good news is that it's not too hard to create your own Fireworks Flex Components (FFC's)and that you can add more styling options quite simply. That's what I will talk about in this post. We will go through the process of creating a simple FFC : a HRule.

There are two files required to make an FFC ; a Firework's png containing a symbol and a jsf file. So to get started create a new file in Fireworks CS3 (I made mine 50 x 5px). Next use the Line tool to create a horizontal line that stretches from the left to the right edge. Select your new line and give it an instance name (top left of the property inspector ; I called mine "line"). Copy and paste the first line, move it down one pixel and change it's opacity to 30 and call it shadow (for reasons I hope are obvious or will be soon). Finally select both lines and select F8 (or Modify > Symbol > Convert To Symbol) to convert your line to a symbol. Name your symbol HRule and select "Save to Common Library" and select "OK". A "Save" dialog appears open to <user settings>\Application Data\Adobe\Fireworks 9\Common Library\Custom Symbols (Windows), or <user name>/Application Support/Adobe/Fireworks9/Common Library/Custom Symbols (Macintosh) directory. If you save your symbol there it will appear in the Common Library panel under Custom Symbols. It must be saved within Common Library to appear within the Common Library. But you can create your own folder within Common Library with a more useful name. The symbol will be saved as ComponentName.graphic.png (in this case HRule.graphic.png). The distrubing thing is that your symbol will disappear from the stage and you'll need to find it within the Common Library and drag it onto the stage to continue.

So far so good! Now we want to create the javascript file that will power the symbol properties and control what MXML is created. To simplify this a kind someone has created a command panel to help with this process. So select the newly created HRule instance and then select Commands > Create Symbol Script. This will open an editor dialog. Select the symbol you want to edit using the button provided. If a symbol script exists for this symbol you will be prompted to import and continue editing that file. Otherwise you can start adding attributes.

The HRule has three style attributes that we'll want to change ; shadowColor, strokeColor, strokeWidth. Select the "+" at the top of the properties area. You'll notice under element name that our two lines are listed. Let's start by selecting "line". Now under attribute select fillColor; this is the Fireworks property that will be changed. Set property name to strokeColor this is what will be displayed in the Symbol Properties panel and written into the MXML. Finally you can select a default color if you wish. Repeat this for shadowColor (the strokeWidth takes a bit more work to get Fireworks to reflect the changes so I'm leaving this out to keep the example clear and simple). You can adjust the order using the arrow buttons at the top right. When you are happy select "Save".

We're nearly there. Just one more step. The script creator does most of the work for us. But I found there was one change needed so locate the jsf file (in the same folder as you saved the symbol) and open it in your preferred editor (Dreamweaver will do fine). Locate a function called "setDefaultValues" near the top of the file and add the following line after the opening curly brace:

Widget.elem.customData["flexClassName"] = "HRule";

In any new FFC's you create exchange HRule for the Flex components name. That should be all we need to do. Now to test it create a new file in Fireworks (say 60x10 px if you used my suggested dimensions). Open the "Common Library" panel if it's closed and select reload from the panel menu. Look for a folder with the same name you saved your HRule into. Open the folder and you will hopefully see your HRule component; drag it onto the stage. You should be able to change the colour of the stroke and it's shadow using the "Symbol Properties" panel.

Finally, go to File > Export and under the export options select "MXML and images" and then "Save". If you open that MXML file you should see an HRule element with the colors you selected. That's it.

HRule is a simple example and we haven't implemented all the available styles. We could easily add the strokeWidth directly to the jsf file (it is defined in the source files). It won't display the changes within Fireworks which limits the usefulness from a design perspective. But it will be included in the MXML file which helps in Flex. A good place to learn more about the possibilities is to take a look at the png and jsf files for the actual Flex Components. To find these look in application_folder/Adobe Fireworks CS3\Configuration\Common Library\Flex Components\. You can get a copy of my source files to help if you get stuck.