Friday, September 25, 2009

Thursday, August 27, 2009

Flex Legend Button: Solved!

Thanks to Marcus and his amazing code I can share with you a soultion for my legend button problem.

This is more than I asked for. Make sure if you use this, you credit and thank Marcus for his amazing work!

Sample with view source enabled

Wednesday, August 26, 2009

Flex DataGrid sorts

Sometimes your data is in a specific order, but not ordered on anything you can really sort by via a data grid. So sometimes you apply a sort with the data grid (or advanced data grid), which is great and everything, but what do you do when you want to reset the data back to the original order?

this.mydatagrid.dataProvider.sort = null;
this.mydatagrid.dataProvider.refresh();

Done!

Monday, August 24, 2009

Flex Image Map

I thought since I mentioned it way back when in a tweet, I should post the code for my selectable map component.

I thought this was going to be super tough, but once I found the ImageMap component in flexlib it wasn't bad at all.

Here is the example with view source enabled.

This example also shows how to create a custom event, which I also mentioned in a previous post.

Wednesday, August 12, 2009

Flex adding an event to call to the parent

So I always have this problem where I'll have a component inside a component, and the parent component needs to do something based on some sort of trigger from the inside component. Using Parent or Application is a big no no, or so my Architect friend tells me ;). They way to do this is create an Event on the inside component. This is pretty easy to do, but I always seem to miss a step and get all frustrated and not understand why it's not working. And in these hot lazy days of summer, it's really not a good motivator. :D

So here are the steps so I can look this up if I forget. I am just going to use a button click as an example, if you need something more intense you'll need to make a custom event.

So... ComponentB is inside ComponentA.

In the actionscript of ComponentB do:

Just below the imports - [Event (name="myEvent", type="flash.events.Event")]

Create a function that dispatches that event:
protected function myFunction():void
{
dispatchEvent(new Event('myEvent'));
}

In the MXML of ComponetB call the function:

<Button id="myButton" click="myFunction()"/>

In the actionscript of ComponentA create a fucntion for what you want the trigger to do:
protected function buttonBClick():void
{
Alert.show("Button in the Panel has been clicked");
}

In the MXML of CompoentA, where you add ComponentB call the event you made:
<ComponentB id="componentB"
myEvent="buttonBClick()"/>

Volia!

Confused? Yeah me too. Here's an example.

Wednesday, July 29, 2009

Extending Flex buttons... can you help me?

**Edit - this has been solved thanks to the help of Marcus: view the entry here**

I never claimed to be a Flex expert... and this only proves why.

Back story: I am trying to extend a Flex button to be something I'm calling a legend button. Essentially it is a button that also doubles as a legend. When the toggle is on that line is on the chart, when the toggle is off that line is removed from the chart. The button 'color' and the line color have to match.

What I am currently trying to do: I am trying to extend the button component and add a Box (10pxx10px). What is happening however, is the box is showing up underneath the button itself, so when the button alpha is 100% (i.e. when toggle is on) you can't see the box.

Here's the code:

package com.view
{
import flash.display.DisplayObject;
import flash.events.MouseEvent;
import flash.text.TextLineMetrics;

import mx.containers.Box;
import mx.controls.Button;
import mx.core.UITextField;

public class LegendButton extends Button
{
[Bindable] public var legendColor:uint;
private var legendIcon:Box;

public function LegendButton()
{
super();
}

override protected function createChildren():void
{
if (!legendIcon)
{
legendIcon = new Box;
legendIcon.styleName = this;
legendIcon.setStyle('backgroundColor',legendColor);
legendIcon.width = 10;
legendIcon.height = 10;
addChild(legendIcon);
}

if (!textField)
{
textField = new UITextField();
textField.styleName = this;
addChild(flash.display.DisplayObject(textField));
}

super.createChildren();
}

protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
this.setStyle('paddingLeft',15);
this.setStyle('paddingRight',5);

legendIcon.move(5,5);

super.updateDisplayList(unscaledWidth,unscaledHeight);
}

override protected function measure():void
{
if (!isNaN(explicitWidth))
{
var w:Number = explicitWidth;
w -= getStyle('horizontalGap') + getStyle('paddingLeft') + getStyle('paddingRight');
textField.width = w;
}
super.measure();
}

override public function measureText(s:String):TextLineMetrics
{
textField.text = s;
var lineMetrics:TextLineMetrics = textField.getLineMetrics(0);
lineMetrics.width = textField.textWidth + 4;
lineMetrics.height = textField.textHeight + 4;
return lineMetrics;
}

}
}


Here's what they look like. Sad isn't it? :(

Tuesday, July 28, 2009

Flex line charts: baseAtZero

baseAtZero... this little property helped save me a lot of code. The client didn't like that the charts were sometimes so squished because the charts always started at 0 but none of the data was close to the zero range. I was going to loop through the data in each chart and set the min and max... but then I discovered this property.


<mx:verticalAxis>
<mx:LinearAxis id="vaxis" baseAtZero="false"/>
</mx:verticalAxis>


All it does basically is stop the chart from forcing the vertical axis start at 0, and therefore starts it based on the data.

Wednesday, July 22, 2009

Flex slidding panels showing off screen

So in the current project I'm working on I have a lot of Panels that slide on and off the screen. The problem I keep having is the Panels are still visible when their x value is set to the width of the container (meaning they are outside of the container but you can still see the edge of the Panel). I was messing around with clip content, etc, and nothing seemed to be working. Eventually I did the following combination and it worked (but still doesn't make much sense to me).

Set the container holding the sliding Panel to includeInLayout = false
Set the sliding panel to clipContent = true (and includeInLayout = true - the default)

Weird, but it works.

Tuesday, July 7, 2009

Adobe Contribute and CSS layouts

One of the charity sites that I designed and built (using divs with CSS layout) want to use Adobe Contribute to manage the site, since they have high volunteer turnover, and it's too much to try to train each one in HTML. Makes total sense right?

So the manager tells me that the menu (which is a absolute positioned div with the highest z-index) is covering up the editable content region.

I've never used Contribute myself, so I downloaded the trial so I could see what she was talking about.

Now in my head I'm thinking, well the menu isn't editable so it shouldn't be showing up in Contribute edit mode at all... but it does... and it does indeed overlap the editable region, which makes it pretty damn difficult to edit! Completely annoying.

But wait... there is more frustration to come.

I start googling, and at first I can't find anything! Eventually I start finding questions on forums like mine, but unfortunitely no one has answered them.

I finally found an ok solution. Hide the CSS in edit/design mode. You can do this through Dreamweaver. The catch? You have to do this step to every html file you have that you want to be able to edit with Contribute.


  1. Open your site in Dreamweaver.

  2. Open one of the html files you want to be able to edit in Contribute.

  3. In the CSS panel menu choose "Design-time..."


  4. Add your stylesheet to the "Hide at Design Time" box.


  5. Save your html file (you'll have to do a small edit like add a space or something to enable save)



In Dreamweaver you can hide the AP "layer", if only it were that easy with Contribute.

If it just looks totally awful, you can create a CSS file that you only show at design time. Just follow the steps above, but add it to the show only at design time box.

If anyone has found a better solution I'd love to know! Please comment here.

Thursday, July 2, 2009

Flex Datagrids and datatips

So you think when you set the showDataTips property on the DataGridColumn to true that that will make the datatip show... WRONG... you also need to set the dataTipField property to your dataField.

So simple... yet this took me half an hour to figure out.

Thursday, June 11, 2009

Flex AdvancedDataGrid Header bug?

I was building an AdvancedDataGrid today, and the 2nd header was supposed to be a date. Easy enough right? Not so much...

I put it as a String, as a Date, as a formatted Date... and every time the last character was begging cut off. No reason why. I tried putting the Date in a String variable... still cut the last character off... but ONLY when it was in the format 5/11/09 or similar... any other string worked fine.

I eventually had to use the headerRenderer... all the renderer (extends Text) does is override the updateDisplayList with this.text = data.headerText.toString();. Works like a charm. What a messed up bug...

Tuesday, June 9, 2009

Flex - Hide and show tab in tabnavigator

I'm not sure why I didn't think of this myself...

http://techmytongue.blogspot.com/2008/11/hide-show-tab-on-tab-navigator.html

This becomes very important if you want to hide tabs in a tab navigator but you don't want to remove them from the interface completely. In my situation I wanted to hide tabs in a tab navigator based on what the user had selected in a data grid. If the user selected another row in the grid I may need to show a tab that I had previously hidden.

tabNav.getTabAt(1).visible = false;


Now to elaborate on Venkatesh's post...

To remove the tab stop, also disable it:
tabNav.getTabAt(1).enabled = false;

Now if you are hiding a tab before another tab (that is not hidden) there will be an empty gap where your tab should be. To fix this:
tabNav.getTabAt(1).includeInLayout = false;

And one final thing. If you're hiding your default tab (i.e. tab index 0) you will also need to set the selected index of the tabNav or else you will still see the contents of the default tab.
tabNav.selectedIndex = 2; //If you were hiding the first 2 tabs (tab 0 and tab 1)


Here is a code snip. In this example there are 3 tabs. Based on the user selection you hide/show the first 2 tabs.

if ( userSelection == "showTabs" )
{
tabNav.getTabAt(0).visible = true;
tabNav.getTabAt(1).visible = true;
tabNav.getTabAt(0).enabled = true;
tabNav.getTabAt(1).enabled = true;
tabNav.getTabAt(0).includeInLayout = true;
tabNav.getTabAt(1).includeInLayout = true;
tabNav.selectedIndex = 0;
}
else if ( userSelection == "hideTabs" )
{
tabNav.getTabAt(0).visible = false;
tabNav.getTabAt(1).visible = false;
tabNav.getTabAt(0).enabled = false;
tabNav.getTabAt(1).enabled = false;
tabNav.getTabAt(0).includeInLayout = false;
tabNav.getTabAt(1).includeInLayout = false;
tabNav.selectedIndex = 2;
}

Wednesday, June 3, 2009

Digital Imaging

What I learned so far in my Digital Imaging course (besides a bunch of theory and PhotoShop shortcuts).

Before


After


This took me maybe a minute and a half to do. I am guessing that after doing it for a while and getting a better eye I could do something like this even faster and make it look even better.

HTML - rounded div corners with CSS (no images)

I am doing an html website and the design I came up with has one rounded corner. I come from way back when we used to use tables and use images to get rounded corners. Although I haven't worked much in HTML in a while, I know the norm now is to use divs instead of tables... so I did some digging and found this:

http://www.html.it/articoli/nifty/index.html

Using stripes with different margins to get a rounded corner look. So clever! It makes total sense, but I would have never thought to do this. To get my ONE rounded corner I had to make some slight modifications. A code snip is below.




<style type="text/css">
body{background-color: #FFF;
margin-right:0; padding-right:0;
margin-left:0; padding-left:0;
font: 100.01% Verdana,Arial,sans-serif}
p{margin: 0 10px}
div#nifty{ margin-left:300px; margin-top:35px; background: #FF0000;}
b.rtop, b.rbottom{display:block;background: #FFF}
b.rtop b, b.rbottom b{display:block;height: 1px;
overflow: hidden; background: #FF0000}
b.r1{margin-left: 5px; margin-top: 0;}
b.r2{margin-left: 3px; margin-top: 0;}
b.r3{margin-left: 2px; margin-top: 0;}
b.rtop b.r4, b.rbottom b.r4{margin-top:0; margin-left:1px; height:2px}
</style>
</head>

<body>

<div id="nifty">
<b class="rtop"><b class="r1"></b><b class="r2"></b><b class="r3"></b><b class="r4"></b></b>

<div style="height:200px"/>

</div>

</body>

Tuesday, April 21, 2009

Flex Column Chart

I need a Column chart that would get both negative and positive numbers, easy enough. The catch is that the negative "columns" are to be red and the positive "columns" are to be green.



Well it wasn't too much fuss to get this figured out, but I thought I would post my code in case it would help anyone else out. Who knew that ColumnSeries had itemRenderers!


<mx:ColumnSeries
xField="Month"
yField="Profit"
displayName="Profit"
itemRenderer="ColorNegativeBarRenderer"
/>


Here's a sample with view source enabled so you can see the item renderer code.

Here's where I found the info I needed:
http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=2&postId=2021

Thursday, April 2, 2009

Removing column header separator lines (flex)

This took me a while to figure out so I thought I would post it on here just in case someone else is having the same problem.

I have an Advanced Data Grid, but I don't want any separator lines between the headers. There are 2 styles and 1 property you need to set in an AdvancedDataGrid to make this happen.



The styles are:
header-separator-skin
header-sort-separator-skin

The property is:
sortExpertMode

I figured setting the styles to "null" would work, but it doesn't.

Here is what you need to do:

headerSortSeparatorSkin="mx.skins.ProgrammaticSkin"
headerSeparatorSkin="mx.skins.ProgrammaticSkin"
sortExpertMode="true"


Or if you'd rather set the styles in CSS:

header-separator-skin: ClassReference("mx.skins.ProgrammaticSkin");
header-sort-separator-skin: ClassReference("mx.skins.ProgrammaticSkin");


Sample with source

Thanks to http://theflexguy.com/index.php?option=com_idoblog&task=viewpost&id=104&Itemid=54 for your post on this!

Friday, March 20, 2009

Tuesday, March 10, 2009

Flex TabNavigator - tab click event?

So there doesn't seem to be any item click or tab click event on the tab navigator in Flex. I find this sort of annoying, I mean surely this would be useful and should be included? When searching all I could find was people saying to either use the change event on the tab navigator, (which didn't help me because I wanted my method to run even if you clicked on the currently selected tab) or to use a tab bar instead (which also didn't help me because I am using the SuperTabNavigator from flexlib).

What I am doing is basically maximizing the tab when it is clicked, and minimizing it if it is clicked again.

I found a solution.
http://www.actionscript.org/forums/showthread.php3?t=135539 (post by stburns).

You basically get the tab's button. It sounds weird, here's the code to how it works.


private function creationComplete():void
{
for (var i:int=0; i<myTabNav.getChildren().length; i++)
{
var tab:Button = myTabNav.getTabAt(i);
tab.addEventListener(FlexEvent.BUTTON_DOWN,tabClickHandler);
}
}

private function tabClickHandler(event):void
{
if (myTabNav.height <= 25)
{
maxTabNav();
} else {
restoreTabNav();
}
}



I really need to start serving these little examples somewhere, it would be way easier for people to understand if they could see it working. I will, I promise. I have just finished the NS SPCA website redesign, so I should have some time.

Also, if you have any worthy causes that need help with their website let me know! I like to keep one charity project on the go.

**EDIT**
Here we go... my first sample with view source!
See sample (right click to view source)

Wednesday, March 4, 2009

Flex ToggleButtonBar with icons

I had a toggle button bar but I wanted to have the buttons have labels AND icons. Knowing and working with Flex for a few years I thought "oh God, how hard is this going to be". It was actually very simple!


<mx:Array id="dp">
<mx:Object label="One" icon="@Embed(source='assets/iconOne.png')"/>
<mx:Object label="Two" icon="@Embed(source='assets/iconTwo.png')"/>
<mx:Object label="Three" icon="@Embed(source='assets/iconThree.png')"/>
</mx:Array>

<mx:ToggleButtonBar id="myBar" dataProvider="{dp}"/>

Monday, February 23, 2009

Flex Checkbox as Grid item editor and renderer

I have a dataGrid with a few columns that are simply check boxes. The kicker is I want the user to be able to edit those check boxes. So I knew the first step, using the renderer to have the data from the data provider show up in a check box, but I had to do some research for the editor part.

Here is the code snip of the DataGridColumn that should help you out if you were trying to do that same thing. (Warning: the textAlign property may only work in Flex 3).


<mx:DataGridColumn
dataField="isOpen"
headerText="Open"
editable="true"
textAlign="center"
itemEditor="mx.controls.CheckBox"
editorDataField="selected"
itemRenderer="mx.controls.CheckBox"/>


The important part to this that I was missing is:
editorDataField="selected"

This returns the value of the 'selected' property to the data provider, otherwise, by default it looks to return the "text" property, which a check box does not have.

Hope that helps someone.

Wednesday, February 18, 2009

Flex Advanced Data Grid remove item

This shouldn't have taken me this long to figure this out... it is really quite simple actually.

I have an AdvancedDataGrid with a Hierarchical data provider. I have a delete button. The behavior I want is when the user clicks the delete button whatever row is highlighted (selected) in the ADG is removed.

To do this you need to use two methods.

The first is the removeChild method. Use this on the dataprovider of the ADG. It takes two arguments, the parent node, and the object to be removed. IF you're object is at the top mode, pass null for the parent node argument.

removeChild(parent,object)

The second is the getParentItem method. This method, you guessed it, returns the parent of the item passed to it.

getParentItem(Object);

Use them together to remove the selected item in your ADG.

myADG.dataProvider.removeChild( myADG.dataProvider.getParentItem(myADG.selectedItem), myADG.selectedItem );

Note, make sure your data provider is bound to the ADG.

Monday, February 9, 2009

Flex Advanced Data Grid - header properties to know

I'm working with another advanced data grid. The grid has a lot of columns and fitting it on one screen without a horizontal scroll is proving challenging. Here are a couple properties regarding headers that I found helpful:

sortExpertMode - Setting this property to true removes that little vertical bar next to your header text. That frees up some horizontal space.

headerWordWrap - Setting this property to true allows multi-line headers. You will need to set the Column width to force the text to wrap, and you'll probably need to set the header height since the default isn't tall enough to fit two lines of text.

folderClosedIcon & folderOpenIcon - Setting these properties to {null} will remove the little folder icon next to the grouped item. You can also use these properties to show a custom icon.

Thursday, February 5, 2009

No more ImageReady

Does anyone else find it annoying that ImageReady was discontinued? Right now I am trying to edit an animated gif, which I would always do in ImageReady, but now that it's not there I'm not sure what to do. When I open an animated gif file Photoshop looses all the data so you can only see the first frame (even tho the animation timeline feature was added to Photoshop CS3??? Can I say... WTF?) The solution they're purposing is to open the gif in Fireworks. Oh, that's great... if you HAVE Fireworks. I have the Adobe Design Premium package - and that doesn't include Fireworks. UGH. I can open it in Flash, but the editing tools in Flash suck. Man oh man... sorry for the vent!

Edit...

My solution for this is as follows:

Open the animated gif in Flash. Then export the movie as MOV file. Open Photoshop CS3. Choose File - Import - Video Frames to Layers...

Window - Animation will show you the animation time line frames thingy.

Again, does anyone else find it ridiculous that a program that can create animated gifs can't open them??? Also sorry that my solution requires Flash.

Tuesday, February 3, 2009

Metro SPCA

Thanks to the people at the SPCA for sending me a thank you gift. It feels great to be appreciated. The NS SPCA gave me an honorary membership, a tote bag, and a certificate of appreciation.

Here is what I did for them:
http://www.metro.spcans.ca/

Monday, January 26, 2009

Flex Advanced Data Grid collapses on refresh

I was having this problem with my Advanced Data Grid. Every time the data refreshed the whole thing collapsed, which isn't a good thing when users have drilled down 3 levels.

I know this is probably a bad way of doing this, but it is the only way I could get to work. All the examples I've seen of this say to just assign the saved openNodes Object to the openNodes property, like this...

myOpenNodes = new Object();
myOpenNodes = IHierarchicalCollectionView(myADG.dataProvider).openNodes

//refresh here

IHierarchicalCollectionView(myADG.dataProvider).openNodes = myOpenNodes;

but that doesn't work!!

Here is what I did:

On the refresh method set the following variables (these variables need to be accessible from all methods inside the component, so put them in your model or make them global, whatever). These variables hold the state of the ADG before the refresh.

//Object holding all currently open nodes
myOpenNodes = new Object();
myOpenNodes = IHierarchicalCollectionView(myADG.dataProvider).openNodes

lastSelectedItem = myADG.selectedItem;

lastScrollPosition = myADG.verticalScrollPosition;


This method loops through every item in the advanced data grid up to the depth you provide (here it is to the depth of 4). Then any time it finds an object that is also in the myOpenNodes object it adds to to an array that then is assigned to the ADG.openNodes property. In this example the property of the grid item I am using to compare is called "Group".

private function selectLastADGItem(evt:Event):void
{
//Array to assign to openNodes property
var savedNodesArray:Array = [];

for(var i:int=1; i<4; i++)
{
var dataCursor:IHierarchicalCollectionViewCursor = myADG.dataProvider.createCursor();

while (dataCursor.current)
{

for each ( var item:Object in myOpenNodes )
{
//Check if current item is in openNodes object
if ( item.Group == dataCursor.current.Group )
{
savedNodesArray.push(dataCursor.current);
}

//Check if current item is the last selected item
if ( item.Group == dataCursor.current.Group )
{
myADG.selectedItem = dataCursor.current;
}
}

dataCursor.moveNext();
}

myADG.validateNow();

//Assign new array to openNodes property IHierarchicalCollectionView(myADG.dataProvider).openNodes = savedNodesArray;

myADG.dataProvider.refresh();
}

//Move vertical scrollbar to last position
myADG.verticalScrollPosition = lastScrollPosition;

}

Wednesday, January 21, 2009

flex: Dictionary Class

Today I was introduced to Dictionaries. No, not the kind that you look up the definitions of words, the Flex code kind. The Class. I was having trouble with this Grid that I am working on, the labels are hard coded in the grid (because of formatting and ordering requirements), and there could be anywhere from 1 to 8 data values that go along with that label. At first I had ArrayCollections with a name property (the label) and the values of each data point, and then I was using methods with return values to get the value I wanted back by looping through the ArrayCollection and looking for the name. This seemed really heavy. I asked a co-worker who is more versed in ActionScript than I am, and he told me about dictionaries. With these you can look up an object via another object rather than an index.

Here are some code snips!

First declare your dictionary object!

private var myDict:Dictionary = new Dictionary();


Then, in a method or event somewhere, populate the Dictionary object with the data. (note - if you're populating the data in the same place, then do it on a preInitialize method).

private function preInit():void
{
myDict["banana"] = {w:2.5, h:8, color:'yellow'};
myDict["apple"] = {w:3.5, h:3.5, color:'red'};
myDict["orange"] = {w:3, h:3, color:'orange'};
}


And to use it.

trace( myDict["apple"].color );
//This will output: red

Tuesday, January 20, 2009

Flex PieChart - fill colors

I think this may only work in Flex 3.

My goal was to get the pie charts and line charts on this one view of the dashboard all to sync up color-wise. (The line chart stuff can be found in an earlier post.)

This will also only work if you know what you'll be getting back so far as items.

Lets say I know I will be getting back the following and I know that I want each slice to have a specific coordinating color.

Hearts - Red
Spades - Blue
Clovers - Green
Stars - Yellow

I would create something called a Fill Function. This is called in the PieSeries tag. Your fill function would consist of a switch statement checking the current item, and assigning its fill. In my example code below I use a Radial Gradient, but you can use SolidColor as well.


private function myFillFunction(item:ChartItem, index:Number):IFill
{
var curItem:PieSeriesItem = PieSeriesItem(item);
var fill:RadialGradient = new RadialGradient();
var g1:GradientEntry = new GradientEntry();
var g2:GradientEntry = new GradientEntry();
g1.alpha = 1.0;
g2.alpha = 1.0;

switch ( curItem.item.yourProperty )
{
case "Hearts":
//Choose uint color values eg: 0xFFFFFF for white etc.
g1.color = LightRed;
g2.color = DarkRed;
break;
case "Spades":
g1.color = LightBlue;
g2.color = DarkBlue;
break;
case "Clovers":
g1.color = LightGreen;
g2.color = DarkGreen;
break;
case "Stars":
g1.color = LightYellow;
g2.color = DarkYellow;
break;
default:
g1.color = LightGray;
g2.color = DarkGray;
break;
}

fill.entries = [g1,g2];
return fill;
}

...
<mx:PieSeries
fillFunction="myFillFunction">
...

Thursday, January 15, 2009

Flex Super Tab Navigator

So I have this dashboard project I'm working on. What I am trying to do is have a TabNavigator that is about half the screen, but give it a maximize button, so that if clicked it fills the whole screen. Sounds easy enough, I've done it with a Panel, but unfortunately it seemed a little too tricky for me and my high design : moderate coding skills. So to Google I went.

You know what annoys me? People who blog about this kind of thing, show the awesome component they created, and don't share even a bit of code. That's what I found. Ugh. I did however discover that flexLib has something called a SuperTabNavigator. The SuperTabNavigator has a close button on each tab, so I figured, maybe I can extend this, better than starting from scratch. It wasn't even as difficult as extending it. It is actually pretty easy to customize. Yay for flexLib.

Here are some actual CODE EXAMPLES of what I did.

First you need the flexLib library. http://code.google.com/p/flexlib/downloads/list, add it by referencing the swc file in your project's library path, like you would Cairngorm.

First here's the SuperTabNavigator, which I placed inside a Canvas.

...
<code:SuperTabNavigator id="mySuperTabNav"
width="100%" height="50%"
y={this.height/2}
popUpButtonPolicy="off"
closePolicy="close_always"
tabClose="maxClick(event)">
<mx:VBox label="testing"/>
</code:SuperTabNavigator>
...


Here is the code for the maxClick method.

...
private function maxClick(event:SuperTabEvent):void
{
//This stops the default close action from happening
event.preventDefault();
//Make sure the tab that was clicked is the one that is selected
event.currentTarget.selectedIndex = event.tabIndex;

//Put your max/restore tab code here!
/*example: mySuperTabNav.y = 0;
mySuperTabNav.percentHeight = 100;*/
}
...


Now... it wouldn't be very user friendly if clicking a close button maximizes the tab navigator, now would it? So through CSS we need to change the icon/button on the tab. Now this is kind of odd, I found this here: http://groups.google.com/group/flexlib/browse_thread/thread/d94196bc6510c49c
.
...
SuperTabNavigator
{
tab-style-name: customTabMax;
}
.customTabMax
{
tab-close-button-style-name: maxIconButton;
}
.maxIconButton
{
upSkin:Embed(source="this/is/image/path.png");
overSkin:Embed(source="this/is/image/path.png");
downSkin:Embed(source="this/is/image/path.png");
disabled-skin:Embed(source="this/is/image/path.png");
}
...


Here's a link to the documentation:
http://flexlib.googlecode.com/svn/trunk/docs/flexlib/containers/SuperTabNavigator.html

See my Sample (right click to view source)

Monday, January 5, 2009

datatipfunction in a linechart

To customize the datatip in a linechart in flex you need to use the datatipfunction property that refers to a function. This function must return a string and take a parameter of type HitData. To get the current VALUE of the line point you're mousing over you need to use LineSeriesItem(hitData.chartItem).yValue - I found this difficult to find out at first.

Here's an example:

private function lcDataTipFunction(hitData:HitData):String
{
var s:String;
s = LineSeries(hitData.element).displayName + "\n";
s += LineSeriesItem(hitData.chartItem).yValue + "\n";
s += hitData.item.Day + " at " + hitData.item.Time;
return s;
}