<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Iwo Banaś - Flex Blog &#187; MXML</title>
	<atom:link href="http://www.iwobanas.com/tag/mxml/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.iwobanas.com</link>
	<description>Adobe Flex and AIR thoughts, custom components, how-to’s...</description>
	<lastBuildDate>Tue, 02 Feb 2010 22:54:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Creating Collapsible Panel in Flex 4</title>
		<link>http://www.iwobanas.com/2009/09/creating-collapsible-panel-in-flex-4/</link>
		<comments>http://www.iwobanas.com/2009/09/creating-collapsible-panel-in-flex-4/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 17:57:39 +0000</pubDate>
		<dc:creator>Iwo Banas</dc:creator>
				<category><![CDATA[Panel]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex 4]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[MXML]]></category>

		<guid isPermaLink="false">http://www.iwobanas.com/?p=230</guid>
		<description><![CDATA[It is quite common in Flex applications (and other RIAs) to divide screen content into two parts: the navigation/configuration panel on the left and the actual content on the right.
The examples of such apps are FlexStore sample and famous Style Explorer.
I followed this pattern in many projects and several times we come to the point [...]]]></description>
			<content:encoded><![CDATA[<p>It is quite common in Flex applications (and other RIAs) to divide screen content into two parts: the navigation/configuration panel on the left and the actual content on the right.<br />
The examples of such apps are <a href="http://examples.adobe.com/flex2/inproduct/sdk/flexstore/flexstore.html">FlexStore sample</a> and famous <a href="http://examples.adobe.com/flex3/consulting/styleexplorer/Flex3StyleExplorer.html#">Style Explorer</a>.</p>
<p>I followed this pattern in many projects and several times we come to the point that navigation/configuration panel requires too much space and that there should be a possibility to minimize it. Probably designers of Style Explorer has a similar idea since their navigation control can be minimized. Unfortunately they haven’t created reusable component to do this.<br />
<span id="more-230"></span></p>
<p>Some time ago I have created the collapsible panel in Flex 3. The idea of this component was to minimize panel by hiding panel content and rotating the header by 90 degree. So that, minimized panel was visible as vertical bar with the title. It was the nightmare to use rotation in Flex 3 since Flex 3 layouts doesn’t care about rotation. Placing component in the right place requires many tricks and extensive usage of trigonometric functions…</p>
<p>When I read that Gumbo (now Flex 4) layouts supports rotation I decided to test it by reimplementing my collapsible panel. Flex 4 definitely passed the test. Spark component architecture is really cool and it is much easier to create reusable/extendible components in Flex 4 than it was before. You can see the result of my work below.</p>
<p>This example is created using 4.0.0.8847, it will not work with SDK shipped with beta 1.<br />
<a title="Sources" href="/wp-content/uploads/collapsible_panel_01/srcview/index.html" target="_blank">View source</a> is enabled, you can download zipped sources from <a title="CollapsiblePanel sources" href="/wp-content/uploads/collapsible_panel_01/srcview/CollapsiblePanel.zip">here</a>.<br />
<iframe src="http://www.iwobanas.com/wp-content/uploads/collapsible_panel_01/CollapsiblePanelExample.html" width="100%" height="350" frameborder="no"></iframe><br />
Following <a href="http://opensource.adobe.com/wiki/display/flexsdk/Gumbo+Skinning">Spark components architecture</a> I have extended Panel class and created new MXML skin.</p>
<h3>Component class</h3>
<p>Below you can find the list of steps taken to create CollapsiblePanel main component class. At first sight this list may look long and complicated but after understanding Spark architecture it is really simple.</p>
<ul>
<li>Adding &#8220;collapsed&#8221; skin state
<pre>
[SkinState("collapsed")]
public class CollapsiblePanel extends Panel
{
</pre>
</li>
<li>Adding new <code>collapsed</code> field indicating if panel is collapsed (invalidating skin state in setter)
<pre>
public function get collapsed():Boolean
{
	return _collapsed;
}
public function set collapsed(value:Boolean):void
{
	_collapsed = value;
	invalidateSkinState();
}
protected var _collapsed:Boolean;
</pre>
</li>
<li>Overriding <code>getCurrentSkinState() </code>function to support &#8220;collapsed&#8221; skin state
<pre>
override protected function getCurrentSkinState():String
{
	return collapsed ? "collapsed" : super.getCurrentSkinState();
}
</pre>
</li>
<li>Adding <code>collapseButton</code> optional skin part
<pre>
[SkinPart(required="false")]
public var collapseButton:Button;
</pre>
</li>
<li>Implementing handler to toggle <code>collapsed</code> property on <code>collapseButton</code> click
<pre>
protected function collapseButtonClickHandler(event:MouseEvent):void
{
	collapsed = !collapsed;
}
</pre>
</li>
<li>Overriding <code>partAdded()/partRemoved()</code> functions to add <code>collapseButton</code> event handler
<pre>
override protected function partAdded(partName:String, instance:Object) : void
{
	super.partAdded(partName, instance);

	if (instance == collapseButton)
	{
		Button(instance).addEventListener(MouseEvent.CLICK, collapseButtonClickHandler);
	}
}
override protected function partRemoved(partName:String, instance:Object) : void
{
	if (instance == collapseButton)
	{
		Button(instance).removeEventListener(MouseEvent.CLICK, collapseButtonClickHandler);
	}
	super.partRemoved(partName, instance);
}
</pre>
</li>
</ul>
<h3>MXML Skin</h3>
<p>The CollapsiblePanelSkin.mxml skin is a copy of default Spark Panel skin with a number of modification. I used <a href="http://opensource.adobe.com/wiki/display/flexsdk/Enhanced+States+Syntax">enhanced styles syntax</a> to modify skin in &#8220;collapsed&#8221; state.</p>
<ul>
<li>Adding &#8220;collapsed&#8221; state
<pre>&lt;s:states&gt;
    &lt;s:State name="normal" /&gt;
    &lt;s:State name="collapsed" /&gt;
    &lt;s:State name="disabled" /&gt;
&lt;/s:states&gt;
</pre>
</li>
<li>Grouping all title bar layers inside one Group tag
<pre>
&lt;s:Group id="titleBarGroup" left="0" top="0" right="0" bottom="0"
     maxHeight="32" rotation.collapsed="90"&gt;
</pre>
</li>
<li>Adding collapse button
<pre>&lt;s:Button id="collapseButton" width="16" height="16" top="7" right="7"
    label="-" label.collapsed="+" toolTip="Collapse" toolTip.collapsed="Open" /&gt;
</pre>
</li>
<li>Excluding contentGroup from collapsed state
<pre>
&lt;s:Group id="contentGroup" left="1" right="1" top="32" bottom="1" minWidth="0" minHeight="0"
     visible.collapsed="false" excludeFrom="collapsed"&gt;
&lt;/s:Group&gt;
</pre>
</li>
<li>Adding transitions
<pre>
&lt;s:transitions&gt;
    &lt;s:Transition fromState="normal" toState="collapsed"&gt;
        &lt;s:Sequence&gt;
            &lt;s:Fade target="{contentGroup}" duration="250" /&gt;
            &lt;s:Parallel targets="{[titleBarGroup, this]}" &gt;
                &lt;s:Rotate target="{titleBarGroup}" duration="250" /&gt;
                &lt;s:Resize target="{this}" duration="250" easer="{collapseEaser}" /&gt;
            &lt;/s:Parallel&gt;
        &lt;/s:Sequence&gt;
    &lt;/s:Transition&gt;
    &lt;s:Transition fromState="collapsed" toState="normal"&gt;
        &lt;s:Sequence&gt;
            &lt;s:Parallel targets="{[titleBarGroup, this]}" &gt;
                &lt;s:Rotate target="{titleBarGroup}" duration="250" /&gt;
                &lt;s:Resize target="{this}" duration="250" easer="{uncollapseEaser}" /&gt;
            &lt;/s:Parallel&gt;
            &lt;s:Fade target="{contentGroup}" duration="250" /&gt;
        &lt;/s:Sequence&gt;
    &lt;/s:Transition&gt;
&lt;/s:transitions&gt;
</pre>
</li>
</ul>
<p>Summarizing,  creating CollapsiblePanel in Flex 4 was much easier than in Flex 3 and the resulting component is of much higher quality. Although understanding Spark components architecture and MXML 2009 may require some time it is definitely worth doing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iwobanas.com/2009/09/creating-collapsible-panel-in-flex-4/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Creating MDataGrid date filter</title>
		<link>http://www.iwobanas.com/2009/07/creating-mdatagrid-date-filter/</link>
		<comments>http://www.iwobanas.com/2009/07/creating-mdatagrid-date-filter/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 12:33:50 +0000</pubDate>
		<dc:creator>Iwo Banas</dc:creator>
				<category><![CDATA[DataGrid]]></category>
		<category><![CDATA[reusable components]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[Flex 3]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[MXML]]></category>

		<guid isPermaLink="false">http://www.iwobanas.com/?p=107</guid>
		<description><![CDATA[In this post I will describe how to create custom filter for MDataGrid (my extension of Flex 3 DataGrid described in one of the previous posts and hosted on http://code.google.com/p/reusable-fx/). I will guide you through creation of date filter as an example.
I consider extensibility one of the most important feature of well designed reusable component [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I will describe how to create custom filter for MDataGrid (my extension of Flex 3 DataGrid described in one of the previous posts and hosted on <a href="http://code.google.com/p/reusable-fx/" target="_blank">http://code.google.com/p/reusable-fx/</a>). I will guide you through creation of date filter as an example.</p>
<p>I consider extensibility one of the most important feature of well designed reusable component and that’s why I am trying to make process of creating new MDataGrid filters as straightforward as possible.</p>
<p><span id="more-107"></span></p>
<p>Following <em>&#8220;Favor object composition over class inheritance.&#8221;</em> rule I decided to split filtering functionality among a number of classes rather than write another thousand lines of DataGrid code. At the first glance the solution may look complicated but after understanding responsibilities of &#8220;filters&#8221; and &#8220;filter editors&#8221; it is really straightforward.</p>
<p><strong>Filter editors</strong> are the components displayed below column header after clicking filter button. Filter editor know nothing about business logic of filtering, their only responsibility is to present current state of the filter to the user and modify filter according to users actions. Filter editor may be any component implementing <a href="/wp-content/uploads/date_filter_01/srcview/source/com/iwobanas/controls/dataGridClasses/filterEditors/IColumnFilterEditor.as.html" target="_blank">IColumnFilterEditor</a> interface. The default implementation of this interface is <a href="/wp-content/uploads/date_filter_01/srcview/source/com/iwobanas/controls/dataGridClasses/filterEditors/FilterEditorBase.as.html" target="_blank">FilterEditorBase</a> class extending Box which is used as a base class for all standard MDataGrid filter editors. In the presented example we will create filter editor in MXML extending <a href="/wp-content/uploads/date_filter_01/srcview/source/com/iwobanas/controls/dataGridClasses/filterEditors/FilterEditorBase.as.html" target="_blank">FilterEditorBase</a> class.</p>
<p><strong>Filter</strong> classes are where actual filtering takes place, they implement <code>filterFunction</code> which is used to eliminate items from MDataGrid data provider. Filters are also responsible for examining MDataGrid and presenting information about MDataGrid content to filter editors. In our example filter will present minimum and maximum dates found in given column. All filters extends <a href="/wp-content/uploads/date_filter_01/srcview/source/com/iwobanas/controls/dataGridClasses/filters/ColumnFilterBase.as.html" target="_blank">ColumnFilterBase</a> class.</p>
<p>To implement date filtering mechanism two classes have to be implemented: filter class (<a href="/wp-content/uploads/date_filter_01/srcview/source/com/iwobanas/controls/dataGridClasses/filters/DateRangeFilter.as.html" target="_blank">DateRangeFilter</a>) and filter editor class (<a href="/wp-content/uploads/date_filter_01/srcview/source/com/iwobanas/controls/dataGridClasses/filterEditors/DateChooserFilterEditor.mxml.html" target="_blank">DateChooserFilterEditor</a>).</p>
<h3>DateRangeFilter</h3>
<p>DateRangeFilter extends ColumnFilterBase class and defines four fields: <code>dataMinimum</code>, <code>dataMaximum</code>, <code>minimum</code> and <code>maximum</code>.</p>
<p><code>dataMinimum</code> and <code>dataMaximum</code> represents a earliest and latest dates found in MDataGrid. These fields are updated by <code>updateOriginalDateRange()</code> function.</p>
<p><code>minimum</code> and <code>maximum</code> defines the range of dates which will be displayed in MDataGrid. By default <code>minimum</code> is set to <code>dataMinimum</code> and <code>maximum</code> is set to <code>dataMaximum</code> which means that all data are displayed (filter is inactive). It is important to call <code>commitFilterChange()</code> function inside <code>minimum/maximum</code> setter to inform MDataGrid that filter value have changed.</p>
<p>DateRangeFilter also overrides two functions defined in ColumnFilterBase:</p>
<p><code>isActive</code> getter checks if filter is active i.e. if it may eliminate any items form MDataGrid. In our case isActive getter simply checks if <code>minimum</code> and <code>maximum</code> differs from <code>dataMinimum</code> and <code>dataMaximum</code>.</p>
<pre>
override public function get isActive():Boolean
{
    return (minimum != dataMinimum || maximum != dataMaximum);
}
</pre>
<p><code>filterFunction</code> checks if item passed as an argument should be eliminated. First date displayed in column associated with this filter is extracted from given item and then it is compared against <code>minimum</code> and <code>maximum</code>. If the value is within the range <code>true</code> is returned (item is not eliminated) other ways <code>false</code> is returned (item is filtered out). If no date is fond for the given item <code>true</code> is returned. <code>filterFunction</code> is called many times for every MDataGrid item so it should not be computationally expensive.</p>
<pre>
override public function filterFunction(obj:Object):Boolean
{
    var value:Date = itemToDate(obj);

    if (value)
    {
        if (minimum &#038;&#038; value < minimum)
        {
            return false;
        }
        if (maximum &#038;&#038; value > maximum)
        {
            return false;
        }
    }
    return true;
}
</pre>
<p>You can find two additional functions in <a href="/wp-content/uploads/date_filter_01/srcview/source/com/iwobanas/controls/dataGridClasses/filters/DateRangeFilter.as.html" target="_blank">DateRangeFilter</a> code: <code>itemToDate()</code> is responsible for extracting date from data item and <code>originalCollectionChandeHandler()</code> refresh <code>dataMinimum</code> and <code>dataMaximum</code> when MDataGrid original collection (copy of data provider) changes.</p>
<h3>DateChooserFilterEditor</h3>
<p><strong>Good news:</strong> creating filter editors in MXML is much simpler than coding filter and the effect is instantly visible!</p>
<p>To make curly brackets binding simpler it is good idea to create strongly typed, bindable reference to filter instance edited by filter editor. The code below is the only code placed in <code>&lt;script&gt;</code> tag of our filter editor:</p>
<pre>
[Bindable]
protected var filter:DateRangeFilter;

override public function startEdit(column:MDataGridColumn):void
{
    super.startEdit(column);
    if (!column.filter || !column.filter is DateRangeFilter)
    {
        column.filter = new DateRangeFilter(column);
    }
    filter = column.filter as DateRangeFilter;
}
</pre>
<p>All you have to do now to create cool filter editor is placing MXML components with appropriate bindings and inline event handlers. Below you can see my proposals how date filter editor may look like.</p>
<p>The simple <a href="/wp-content/uploads/date_filter_01/srcview/source/com/iwobanas/controls/dataGridClasses/filterEditors/DateChooserFilterEditor.mxml.html" target="_blank">DateChooserFilterEditor</a> consists of two DateChoosers and reset button.<br />
<a title="Sources" href="/wp-content/uploads/date_filter_01/srcview/index.html" target="_blank">View source</a> is enabled, you can download zipped sources from <a title="MDataGrid date filter sources" href="/wp-content/uploads/date_filter_01/srcview/DateFilterExample01.zip">here</a>.</p>
<p>For better experience <a href="/wp-content/uploads/date_filter_01/DateFilterExample.html" target="_blank">open example in separate window</a>.</p>
<p><iframe src="http://www.iwobanas.com/wp-content/uploads/date_filter_01/DateFilterExample.html" width="100%" height="560" frameborder="no"></iframe></p>
<p>To save some space I have replaced DataChoosers with DateField and created <a href="/wp-content/uploads/date_filter_02/srcview/source/com/iwobanas/controls/dataGridClasses/filterEditors/DateFieldFilterEditor.mxml.html" target="_blank">DateFieldFilterEditor</a>.<br />
<a title="Sources" href="/wp-content/uploads/date_filter_02/srcview/index.html" target="_blank">View source</a> is enabled, you can download zipped sources from <a title="MDataGrid date filter sources" href="/wp-content/uploads/date_filter_02/srcview/DateFilterExample02.zip">here</a>.</p>
<p>For better experience <a href="/wp-content/uploads/date_filter_02/DateFilterExample.html" target="_blank">open example in separate window</a>.</p>
<p><iframe src="http://www.iwobanas.com/wp-content/uploads/date_filter_02/DateFilterExample.html" width="100%" height="350" frameborder="no"></iframe></p>
<p>Of course dates may be filtered in many different ways. For example date filter editor may consist of two NumericSteppers to select years. I hope now you can create such filter editor by yourself.</p>
<p>If you have any questions or suggestions don&#8217;t hesitate to add a comment!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iwobanas.com/2009/07/creating-mdatagrid-date-filter/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
	</channel>
</rss>
