Building Blocks

28Apr/087

Enumerating data types in Actionscript 3 (AS3)

In computer programming, an enumerated type is an abstract data type used to model an attribute that has a specific number of options (or identifiers) such as the suit of a playing card (i.e. a Club, Diamond, Heart or Spade). Using this type allows the program to handle the attribute more efficiently than a string while maintaining the readability of the source code.
-from Wikipedia

I've found this method (illustrated in code below) for enumeration of datasets to be useful, and at this point even essential, in my applications. Prior to this I was actually cutting and pasting the arrays that I was using in my various combo boxes and other selection components as dataProviders. By breaking the dataset into an enumeration class, it makes it easy to maintain the list and lets the dataset function as a first class citizen, ensuring that your data is consistent throughout the application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package enum
{
	/**
	 * CloudTypeEnum enumerates cloud types.
	 * @author JHooks
	 *
	 */
	public class CloudTypeEnum
	{
		public static const NONE:CloudTypeEnum			= new CloudTypeEnum( "None",	   -1 );
		public static const CUMULUS:CloudTypeEnum		= new CloudTypeEnum( "Cumulus", 	0 );
		public static const STRATUS:CloudTypeEnum		= new CloudTypeEnum( "Stratus", 	1 );
		public static const CIRRUS:CloudTypeEnum		= new CloudTypeEnum( "Cirrus", 		2 );
		public static const NIMBUS:CloudTypeEnum		= new CloudTypeEnum( "Nimbus", 		3 );
 
		public var value:String
		public var ordinal:int
 
		/**
		 * CloudTypeEnum constructor
		 * @param value
		 * @param ordinal
		 *
		 */
		public function CloudTypeEnum( value:String, ordinal:int )
		{
			this.value = value;
			this.ordinal = ordinal;
		}
 
		/**
		 * A list of cloud types
		 * @return
		 *
		 */
		public static function get list( ):Array
		{
			return [ CUMULUS,
					 STRATUS,
					 CIRRUS,
					 NIMBUS ];
		}
 
		/**
		 * A list of cloud types appropriate for use in ComboBox and other
		 * selection components as a DataProvider
		 *
		 * myComboBox.dataProvider = CloudTypeEnum.cList;
		 * @return
		 *
		 */
		public static function get cList( ):Array
		{
			return list.unshift( NONE );
		}
 
		/**
		 * Select a cloud type by its value property
		 * @param value
		 * @return
		 *
		 */
		public static function selectByValue( value:String ):TaskTypeEnum
		{
			for each ( var cloudType:TaskTypeEnum in CloudTypeEnum.list )
			{
				if ( value == cloudType.value )
					return cloudType;
			}
 
			return NONE;
		}
	}
}

Thanks to Cliff Hall who showed this to me via one of his PureMVC demo applications. For the life of me I can't remember which one.

21Apr/085

Continuous scrolling image thumbnail component for Flex.

I've updated this to a proper component implementation that can be found here.

Here is the beginnings of a full featured open-source continuous scroll thumbnail component for Flex. It is rough right now, but I plan to polish it and make it something useful. This format is really appealing, as it gives the user a seamless view of a gallery, without any jumps or aggravating scroll bars. Up until now I have been using H and V Lists in flex for my thumbnailing, but they are ugly and don't provide as rich of an experience.

The Scroll Panel from AFComponents was my first choice. It is a very nice component, well priced, and would be just what I need, if not for the fact that my project is open-source and using a commercial component sorta kills the whole thing. After scouring the internet I finally stumbled upon the work Peter Wright has put in on a perpetual scrolling list.

I've modified it to accept an XML list of image objects, as well as perform horizontally. It is also functioning as a slideshow, and I want to allow it to go either H or V depending on the need. It should shape up to be a nice reusable component. Much thanks to Peter for supplying the code to get me started.

Source Enabled

20Apr/0813

Using the Senocular AS3 TransformTool in Flex

Hey,I am so interested about that you had ever used the ‘TransformTool’ library in your Flex project. But there is little examples showing how to use it in flex, Would you please share some example about how to use ‘TransformTool’ in Flex? I have tried as such a way:

but it failed at line
canvas.addChild(defaultTool);
Can you give any hints? Thanks.

Like most pure AS3 display classes, the TransformTool needs to be added to a UIComponent wrapper to function properly in Flex.

Source.

25Mar/081

Renju – AS3 board game built with the PureMVC framework.

renju.jpg

This is awesome. Here is a polished board game with nice graphics and sounds - full AI - and best of all, the complete source. This is a great example of PureMVC in action. All of the projects on Actionscript Notes utilize PureMVC, and the owner seems to be generous with the source. Many thanks for that.

23Mar/080

Christian Cantrell's ever-growing selection of useful Actionscript 3/AIR libraries.

Here's the full list of what he has on Google Code.

The CoreLib is essential, but he's been busy writing useful libraries for AIR. I've used the notification library, which has some great features and makes notifications on the desktop sensible. The exchange library is interesting, for sure. They are all worth checking out.

There are also a number of interesting example applications using AIR, including a motion detection application, an Amazon S3 interface, a screen saver, and an MS Exchange calendar.

23Mar/082

I had an epiphany as to what polymorphism is last night.

Yes, I know I am late to the party. I can't even estimate how many times I've read a definition of an Interface over the last year. It has been a concept that totally baffled me for a long time, then I sorta understood, and last night I actually implemented an Interface intentionally and correctly. The same is true for the term polymorphism. I can read definitions until my eyes hurt, but until I actually use it, the words are just abstractions. These two concepts are synonymous, as Interfaces in Actionscript 3 are a convenience for type-checking polymorphism in APIs.

'Ah-ha!'

In this case, I had a Flex container that I wanted to pass to a method. I didn't know what the container would be, but I knew that it would be a container. IContainer? Yup. Now the method couldn't care less what class is being passed its way, as long as it has the appropriate methods that match the IContainer signature.

Now it makes sense. This is the reason I keep reading that I need to use implicit getters and setters with private class properties instead of public properties. Public properties are not allowed in an interface, so you aren't able to abstract these properties with an interface. Getters and setters ARE allowed in an interface, so now you can expose these properties and ensure that methods expecting the interface get what they are looking for. As it turns out, people weren't recommending this simply to get me to write extra lines of code ;)

The pieces are starting to come together. Abstract classes, design patterns, polymorphism, interfaces... PureMVC has been a help. The framework pushes me towards proper OOP and the use of design patterns. Stacking knowledge, one block at a time.

18Mar/084

Accessing a List from its itemRenderer

This was really throwing me off tonight. I could not figure out how to get at the List from its itemRenderer. this.parent... no this.owner... no

So I started The Search™, trying to hunt down The Answer™. This is one of those things that doesn't just jump out of the manual at you. Luckily, Peter Ent is running an extremely informative series on itemRenders. He says to get at the List, we need to simply access the listData property. But there's a catch:

Most controls such as Text, Label, Button, CheckBox, and so forth, implement IDropInListItemRenderer. Most containers, such as HBox, Canvas, etc. do not implement that interface. If you want to use listData in an itemRenderer that extends a Container you will have to implement IDropInListItemRenderer yourself - I'll cover that in the next article.

Luckily for us, it is a simple process:

1
<mx:hbox xmlns:mx="http://www.adobe.com/2006/mxml" implements="mx.controls.listClasses.IDropInListItemRenderer"></mx:hbox>

We will need to implement the appropriate methods in the itemRenderer's Script tag also:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import mx.controls.listClasses.BaseListData;
 
private var _listData:BaseListData;
private var list:List;
 
public function get listData() : BaseListData
{
	return _listData;
}
public function set listData( value:BaseListData ) : void
{
	_listData = value;
	list = listData.owner as List
	list.addEventListener( ListEvent.CHANGE, onListChange, false, 0, true )
}

In my case, I wanted to listen for changes so that I could set one of the itemRenderer sub-component's properties whenever the list had changed. Now to access the List:

if ( list.selectedItem == data ) doSomeStuff();

Easy as that.

Filed under: actionscript, flex 4 Comments
15Mar/089

5 reasons PureMVC kicks ass

PureMVC is a lightweight MVC framework originally written for Actionscript 3, but which has subsequently been ported to a host of other platforms. I'm a PureMVC fan boy. There is no denying it. Here are few reasons why:

Simplicity
There are a few MVC frameworks available for Actionscript 3. None of them are, well... as pure. PureMVC is simple by design. It doesn't provide you with a lot of bells and whistles. What it does is provide a solid foundation upon which to add your own functionality in limitless ways. The framework itself is simple. 'Make it as simple as possible, but no simpler,' said Albert Einstein. This is one of the core goals of PureMVC.

Community
The PureMVC community is growing. The Architect's Lounge has high signal to noise ratio. Cliff makes a super human effort to personally answer every question that is posted. Among the helpful community members is Chandima Cumaranatunge, the co-author of a book that anybody interested in OO Actionscript should own, Actionscript 3 Design Patterns.

Cliff has created the PureMVC Manifold Project, which provides a well crafted central location for official PureMVC releases, and a host of ports, demos, and utilities developed by the community. This wealth of information provides a high quality code base to use and learn from.

Reusability
As you can see by poking around the Manifold Project, there are a lot of utilities and modules already available. The basic structure of a PureMVC project naturally lends itself to the creation of common classes that can be reused across many projects. Major components don't care who is sitting beside them. They happily wait for their notifications and respond without considering their neighbors. In some circles this would be considered rude, but in a PureMVC application this gives a wonderful, loosely couple application that can be refactored and recycled.

Portability
The port to Python is done!  PureMVC is on Flex, Flash, AIR, FlashLite, Python, .NET, Windows Mobile, Silverlight, J2ME, SE, EE, JavaFX, PHP and ColdFusion. This speaks to the simplicity of the framework. It is so fundamental, that most of the ports were just straight translation.

Cliff
Cliff is samurai. He is the benevolent, tireless dictator that any flowering project needs. He is actively engaged with the community. On a daily basis he is on the forums answering questions. The structuring of the ever-expanding pile of resources and information into something useful is daunting task. There it is with the Manifold Project. It is inspiring to see someone so passionate about what they do, and channeling that passion back at anyone interested in learning.

Thanks Cliff, your efforts are greatly appreciated.

14Mar/082

Complex DataGrid filterFunction in Flex/Air

So I need to add robust user controlled filtering options in the application I am working on. This problem has dogged me for a month or two, with my co-workers politely insisting on more and better ways to filter their data. This is completely understandable. When you are staring down a datagrid that is virtually 12 feet long, getting to what you actually want to see is important.

This 2006 article from Bruce Phillips was a big help in the basic concept of multiple input filtering. As is his normal style, it is littered with good references to the source material from his research. This is only considering two filter parameters, however, and I need to consider n parameters, that will probably shift as the needs of the end user grow.

The problem is that each new filtering parameter exponentially increases the complexity of the filterFunction. I can see the pattern, but I haven't quite reached the epiphany that I need to break it down into one of those tight little functions I see real programmers creating (unfortunately, I haven't seen any that address my specific problem).

I thought I'd share my naive, and perhaps confusing filterFunction. It would be great to hear how others approach this problem, and come up with a concise solution.

This function utilizes a TextInput to get text search input from the user. It uses
a series of CheckBoxes for various status condition to generate an array [ 1, 0, 1, 1 ]
to represent their on/off state. It also uses two combo boxes to filter by staff members
as well as clients.

filterFunction:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
private function filterCases(item:CaseVO):Boolean
{
	//is the item visible or hidden
	var result:Boolean = false;
	//array of CheckBox.selected property values
       // in handy ones and zeroes. This is returned from a function
       // that takes the actual CheckBoxes as input and gives me this.
	var case_mask:Array = [ 1, 0, 1, 1 ];
        //a couple VOs to verify the selectedItem in the ComboBoxes.
	var client:PersonVO;
	var expert:PersonVO;
	//array iteration variable
	var i:int;
 
	var dateFormat:DateFormatter = new DateFormatter( )
	dateFormat.formatString = 'MM/DD/YY'
 
	//text search
	if ( caseGrid.filter.caseNumInput.text.length &gt; 0 )
	{
		var searchResult:Boolean = ( ( String( '0' + item.case_id.toString() ).search( caseGrid.filter.caseNumInput.text ) &gt;= 0 ) ||
										( item.style.toLowerCase().search( caseGrid.filter.caseNumInput.text.toLowerCase() ) &gt;= 0 )  );
		if( item.description )
		{
			searchResult = searchResult || ( item.description.toLowerCase().search( caseGrid.filter.caseNumInput.text.toLowerCase() ) &gt;= 0 )
		}
 
		if ( item.client_id )
		{
			searchResult = searchResult || ( personProxy.personFromId( item.client_id ).fullName.toLowerCase().search( caseGrid.filter.caseNumInput.text.toLowerCase() ) &gt;= 0 )
		}
 
		if ( item.date_of_accident )
		{
			searchResult = searchResult || ( dateFormat.format(item.date_of_accident).search( caseGrid.filter.caseNumInput.text ) &gt;= 0 )
		}
 
		for ( i = 0; i &lt; case_mask.length; i++ )
		{
			if ( caseGrid.filter.client.selectedItem is PersonVO )
			{
				client = caseGrid.filter.client.selectedItem
 
				//is an expert selected for filtering also?
				if ( caseGrid.filter.expert.selectedItem is PersonVO &amp;&amp; searchResult)
				{
					expert = caseGrid.filter.expert.selectedItem;
					//filter for client, expert, and status
					if ( (case_mask[i] &amp;&amp; item.status == String( i + 1 ) )
							&amp;&amp; item.client_id == client.id
							&amp;&amp; item.expert_id == expert.id &amp;&amp; searchResult  )
						result = true;
				}
				else
				{
					//filter for client and status
					if ( (case_mask[i] &amp;&amp; item.status == String( i + 1 ) )
							&amp;&amp; item.client_id == client.id &amp;&amp; searchResult  )
						result = true;
				}
			}
			else if ( caseGrid.filter.expert.selectedItem is PersonVO )
			{
				expert = caseGrid.filter.expert.selectedItem;
				for ( i = 0; i &lt; case_mask.length; i++ )
				{
					//filter for expert and status
					 if ( (case_mask[i] &amp;&amp; item.status == String( i + 1 ) )
					 		&amp;&amp; item.expert_id == expert.id &amp;&amp; searchResult  )
					 	result = true
				}
 
			}
			else
			{
				//filter for client and status
				if ( (case_mask[i] &amp;&amp; item.status == String( i + 1 ) )
						&amp;&amp; searchResult  )
					result = true;
			}
		}
	}
	//see if a client is selected for filtering
	else if ( caseGrid.filter.client.selectedItem is PersonVO )
	{
		client = caseGrid.filter.client.selectedItem
		for ( i = 0; i &lt; case_mask.length; i++ )
		{
			//is an expert selected for filtering also?
			if ( caseGrid.filter.expert.selectedItem is PersonVO )
			{
				expert = caseGrid.filter.expert.selectedItem;
				//filter for client, expert, and status
				if ( (case_mask[i] &amp;&amp; item.status == String( i + 1 ) )
						&amp;&amp; item.client_id == client.id
						&amp;&amp; item.expert_id == expert.id  )
					result = true;
			}
			else
			{
				//filter for client and status
				if ( (case_mask[i] &amp;&amp; item.status == String( i + 1 ) )
						&amp;&amp; item.client_id == client.id  )
					result = true;
			}
		}
	}
	//client isn't selected, check the expert filter.
	else if ( caseGrid.filter.expert.selectedItem is PersonVO )
	{
		expert = caseGrid.filter.expert.selectedItem;
		for ( i = 0; i &lt; case_mask.length; i++ )
		{
			//filter for expert and status
			 if ( (case_mask[i] &amp;&amp; item.status == String( i + 1 ) )
			 		&amp;&amp; item.expert_id == expert.id  )
			 	result = true
		}
 
	}
	//finally, filter for the status
	else
	{
		for ( i = 0; i &lt; case_mask.length; i++ )
		{
			//filter for status
			if ( case_mask[i] &amp;&amp; item.status == String( i + 1 ) )
				result = true;
		}
	}
 
	return result
}

You can see that I am repeating myself from the top down to the final else statement, cutting the filter parameters down like a layer cake. It works, and is relatively quick on a grid with 1500 or so items. This just screams "REFACTOR ME" every time I see it.

Filed under: actionscript, AIR, flex, OCD 2 Comments
9Feb/0816

VEsession – Flex photography studio management and client ordering application

My wife saw the application that I am working on at work to manage tasks and immediately asked, "Where's mine?"

21st century honey-do list.

So far, this is what I have created. PureMVC is the underlying framework. The photos are loaded from SlideShowPro Director XML galleries. Unforutately, the most recent version of SSP-D won't let you use it as a service in this way. This older version is has all the functionality I need though, so it isn't an issue. Eventually I will implement functionality to eliminate the need for SSP-D with some gallery management. It will be better to keep it all under one roof.

The backend is Django using pyAMF for communications back and forth. Django elminates the pain of CRUD operations and provides an excellent admin interface for free.

My goal is to open source the application and provide it as a PureMVC/Django example.

UPDATED: This version is a little jacked because I am working on a new version. The demo images are way too big and cause the application to scroll in unsightly ways. The new demo is located here, and uses the same credentials as below.

[Here is the demo]
user: demo_client
pass:demo_client

session_sshot.jpg

[source]

Do to some, uh, laziness on my part, this will only compile with strict mode turned off The new version does not have this problem.