Thursday, November 16, 2006

A Contribution to Flex Search

Yesterday, Ted Patrick released Alpha 1 of the flex.org search. It is a search engine designed specifically to search Flex resources, to help developers find the answers that they are looking for quickly and easily. It is still in its early phases now, but could prove to be a very useful tool for many people.

I took a few minutes to play around with Ted's code and came up with a minimalist interface for the search, with inline previews of the content. Just enter a search query, click on a row, and POW, its right there inline with the code. It uses the Flex-Ajax bridge to listen for the itemClick event on the datagrid, so that there is very minimal user interaction necessary.

You can check it out here...

http://www.cynergysystems.com/blogs/blogs/andrew.trice/flex_search/bin/search.html



Wednesday, November 08, 2006

I'll be speaking at the CAFUG on December 6th

It's official... I'll be speaking at the Capital Area Flex User Group meeting in Rockville, MD on December 6th. Come on out and join us if you are interested. I'm planning to demonstrate how to take full advantage of CSS styles and skinning to polish the UI of your Flex application. This will include (but not necessarily limited to) CSS based layout, custom css styles for components using mx:Metadata, an introduction to the drawing API, and application skinning using image-based and programmatic skins. I hope to see you there!

To register, or for more information, you can visit http://www.dc-flex.org/

Making Flex ... less Flex like: A foray into programmatic skinning

Before I really get into this topic, I have to thank Adobe for opening up the Flex 2 framework. There is so much that I have learned about the inner workings of Flex by examining the framework. For those that have not looked at it, I HIGHLY encourage you to do so. You can learn a great deal about components, containers, drawing/skinning, etc... You can download the framework from flex.org. If you have Flex Builder installed locally on Windows, it is located at C:\Program Files\Adobe\Flex Builder 2\Flex SDK 2\frameworks\source.

On to the real meat here...

One of the key features that sets the Flex/Flash platform apart from traditional web development is that we have the drawing API. You can quickly and easily use the drawing API to programmatically draw images on the screen. You can draw a line from point A to point B to visualize data, visually separate logical groupings of information, encapsulate funcationality, etc... Adobe has done us all a huge favor by creating lots of reusable components within the Flex framework, but eventually, most Flex applications are going to look the same. Don't take this the wrong way; I'm not saying they are going to look bad. The Flex framework has a very clean look to it, and I like it. For most applications this is more than enough.

In order to set your application apart from the rest, you need to look into styling and skinning. You can use CSS styles to customize the color schemes of your application. You can use skins to completely change how a component looks, including the image and/or shape of that component. You can create skins that are images (and embed them within your application), or you can create programmatic skins. Programmatic skins are instructions to the Flash environment to use the drawing API to literally draw your component on the screen. Some great resources to get started with skinning are: Another great place to look for skinnning reference is the Flex SDK source for the halo skin. I was inspired by Kevin Hoyt's Accordion example from last February to look into Flex skinning some more. So I decided to make my own. Here's a screenshot of my customized accoridion skin...



I started by looking at the framework source for the halo AccordionHeaderSkin .as file. I literally copied the file to my workspace, then started chopping it up to suit my needs. Using the framwork source as a base, you can see how the color schemes are taken from the halo theme, and you can reuse them. I created a function that draws the component shape. Before I call that function, I set the line style and the gradient fill (based off of the existing code).
g.lineStyle( 1, borderColor );
g.beginGradientFill( GradientType.LINEAR, selectedFillAlphas, [1, 1], [], verticalGradientMatrix(0, 0, w, h) );
drawSkin( g, w, h, indent, inset );
g.endFill();
private function drawSkin( g: Graphics, w : Number, h : Number, indent : Number, inset : Number ) : void
{
g.moveTo( 0, indent );
g.lineTo( indent, 0 );
g.lineTo( inset, 0);
g.lineTo( inset + indent, indent/2 );
g.lineTo( w-(indent/2), indent/2 );
g.lineTo( w, indent );
g.lineTo( w, h-indent );
g.lineTo( w-indent, h-1 );
g.lineTo( w-(inset + indent), h-1 );
g.lineTo( w-(inset + indent*2), h-(indent/2)-1 );
g.lineTo( 0, h-(indent/2)-1 );
g.lineTo( 0, indent );
}
I took this same approach with the Tab navigator and panel skins also. For the Tabnavigator class, I modified the halo TabSkin.as file. For the Panel, I mofified the BorderSkin.as file. The colors all all reused from the existing halo theme, and the corners on the TabSkin reuse the cornerRadius style from the halo theme.





Once you have created you skins, you need to apply them to your application using CSS. You have to set the skin in CSS for each state that applies:
.tabSkin
{
cornerRadius: 10;
upSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
overSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
disabledSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
downSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
selectedUpSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
selectedDownSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
selectedOverSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
selectedDisabledSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
}

.accordionHeaderSkin
{
upSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
disabledSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
selectedDisabledSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
overSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
downSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
selectedUpSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
selectedOverSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
selectedDownSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
}
You can see the final result in the screenshots below. There are three screenshots: the only differences in the three are changes in the Application css definition to change the theme color and the background gradient colors:
Application 
{
backgroundColor:#FFFFFF;
backgroundGradientColors: #999999, #0000FF;
backgroundGradientAlphas: 0.5, .5;
themeColor: #0000FF;
}






Feel free to contact me with any questions or comments at andrew.trice[ at ]cynergysystems.com