Dec 29 2004
Flex MXML Sample 4: Custom AccordionHeader class
It’s vacation time, so I finally had the opportunity to do some Flex coding again. Sorry for the lack of good posts lately, growing business has kept me from doing a lot of coding (I am currently focussing more on sales and business development).
Today I’ve been working with Martijn de Visser on customizing the header of an Accordion Menu. Honestly, it’s not the easiest thing to find out how to do, especially if you decided not to extend the Button class like the default header does. Martijn describes a bit of the process we did go through and posted a sample and the source code for download. We still have not found a complete solution that we consider production ready, unfortunately there are a few minor focus management issues. I’ve also copied the code into the detailed section of this item.
Our struggle is mainly due to the lack of documentation on this specific part of extensibility in Flex. I wonder how many developers have already been looking into this area, I think not many (apart from iteration:two maybe)?
I have already submitted a request to the Flex team to work on more documentation for this, I hope they will listen when they get back from their holiday. I am mainly looking for answers to questions as What should be taken into account when extending f.e. a Box? I did see some style related tricks in the default class but it’s very difficult to decide what needs to be done in a custom class extending something else (if it should be done at all).
Update:
I found the sample skin C:Program FilesMacromediaFlex 1.5
esources hemesprogrammaticsamplethemeSampleAccordionHeaderSkin.as. I completely forgot about programmatic skinning and don’t know whether it really is a better approach, but it’s definitely worth to investigate a bit more.
headerClassTest.mxml (application file)
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.macromedia.com/2003/mxml” themeColor=”#000000″>
<mx:Accordion id=”acc” headerClass=”AccordionHeaderWithSummary” height=”300″ width=”400″>
<mx:VBox label=”My First Label” toolTip=”Some Summary Data” backgroundColor=”#FF0000″>
<mx:Label text=”Content A” />
</mx:VBox>
<mx:VBox label=”My Second Label” icon=”@Embed(‘complete-flag.gif’)” toolTip=”More Summary Data”>
<mx:Label text=”Content B” />
</mx:VBox>
<mx:VBox label=”My Third Label” toolTip=”Even more Summary Data”>
<mx:Label text=”Content C” />
</mx:VBox>
</mx:Accordion>
</mx:Application>
AccordionHeaderWithSummary.mxml (custom header renderer)
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:HBox xmlns:mx=”http://www.macromedia.com/2003/mxml” xmlns=”*” tabEnabled=”true”><mx:Script>
<![CDATA[
import mx.core.UIObject;
import mx.skins.RectBorder;
import mx.containers.Container;
var content_mc:Container;
/**
* @private
* SymbolName for object
*/
static var symbolName:String = “AccordionHeaderWithSummary”;
/**
* @private
* Class used in createClassObject
*/
static var symbolOwner = AccordionHeaderWithSummary;
var className:String = “AccordionHeaderWithSummary”;
private var focus_mc:MovieClip;
// This function is triggered by Accordion.as
function setState(b:Boolean){
myButton.setState(b);
}
function drawFocus(isFocused:Boolean):Void
{
// Accordion header focus is drawn inside the control.
if (isFocused)
{
if (focus_mc == undefined)
focus_mc = createObject(“FocusRect”, “focus_mc”, 10);
focus_mc.move(1, 1);
focus_mc.setSize(layoutWidth – 2, layoutHeight – 2, 0, 100,
getStyle(“themeColor”));
focus_mc._visible = true;
}
else if (focus_mc != undefined)
{
focus_mc._visible = false;
}
}
function clickHandler(obj):Void{
_parent.headerPress(obj);
// This does not have any effect, at least not the one I was hoping for: If focus is on an other component,
// clicking inside the header and then using navigation Keys does not bring the focus back into the parent
// accordion component. Maybe instead of setting focus on the parent it might help to tweak the focus manager
// directly?
//_parent.setFocus();
}
/**********
RollOver effects not implemented. The original AccordionHeader extended Button, and this the header was a button
with all it’s visual effects. Now the visual effects are also created by a Button – AccordionHeaderButton – but
since it’s nexted in the HBox, we don’t need to create workarounds to follow the Halo border specs as described
in AccordionHeader.as (?)
/**********/
/**********
layoutContents()
NEED TO INVESTIGATE WHAT TO DO WITH THIS, BECAUSE THERE NOW IS A SECOND LABEL
This was originally used to support left alignment of label text, but since
that will be a very uncommon use case, it is not taken into account now
**********/
]]>
</mx:Script><AccordionHeaderButton
id=”myButton” tabEnabled=”false” label=”{label}” icon=”{icon}” width=”150″ click=”clickHandler(this)” />
<mx:Label id=”myLabel” text=”{toolTip}” />
</mx:HBox>
AccordionHeaderButton.as (asset based on default header class)
//****************************************************************************
//Copyright (C) 2003-2004 Macromedia, Inc. All Rights Reserved.
//The following is Sample Code and is subject to all restrictions on
//such code as contained in the End User License Agreement accompanying
//this product.
//****************************************************************************import mx.controls.Button;
class AccordionHeaderButton extends Button
{
/**
* @private
* SymbolName for object
*/
static var symbolName:String = “AccordionHeaderButton”;
/**
* @private
*
*/
var ignoreClassStyleDeclaration:Object = { Button: 1 };
/**
* @private
* Class used in createClassObject
*/
static var symbolOwner = AccordionHeaderButton;
var className:String = “AccordionHeaderButton”;// Disable skins
var falseUpSkin:String = “AccordionHeaderSkin”;
var falseDownSkin:String = “AccordionHeaderSkin”;
var falseOverSkin:String = “AccordionHeaderSkin”
var falseDisabledSkin:String = “AccordionHeaderSkin”;
var trueUpSkin:String = “AccordionHeaderSkin”;
var trueDownSkin:String = “AccordionHeaderSkin”;
var trueOverSkin:String = “AccordionHeaderSkin”;
var trueDisabledSkin:String = “AccordionHeaderSkin”;
// Overrides
var btnOffset:Number = 0;
function AccordionHeaderButton()
{
}
}
2 responses so far
where is complete-flag.gif? please post it so we could test your code and get it to look the way you intended
Golan, you can replace it with any other small icon that you have on your machine.