Archive

Archive for December, 2011

ApacheFlex :: What can happen with a new beginning

December 30th, 2011 Michael Schmalle No comments

Hi,

Well just a quick note to those that are following the direction of Flex, now ApacheFlex podling. I think an important thought we should be thinking about now is how can the SDK and tools be transformed into something that does something new. This thought is for the future and needs to stay in sight if the SDK and tools are to evolve with the changing times.

I will still stand with my opinion that the idea of Flex is powerful as an abstraction to a programming problem that is ever present in the rich graphical and data centric world we live in today. Having written a framework for AS3 reading and writing source code, that is all it is; a language that describes lexical meaning of a problem to be expressed.

So what the heck does this mean? I see compilers as a gateway of transforming something to something else. We have compilers everywhere from text to speech, music sound to notation, color to paintings. ApacheFlex can take our technical imagination into places where is was not able to go. For now, Flex is AS3 and AS3 is the Flash Player, allowing a language that is proven to work well, minus the fat and needless abstraction with to many dead ends, the idea of Flex can become whatever we want it to be with a mature language such as ActionScript3 to express in a very easy way how to get there.

A new framework from the ground up, who knows but I’m glad I get to put my programming/development skills where my mouth is now. :)

A lot of us just want to see the podling child grow up a bit and become a first class citizen in the new mobile and desktop melting pot we call technology.

Mike

Categories: apacheflex Tags:

Flex’s future :: A component developers take 2

December 20th, 2011 Michael Schmalle 2 comments

Hi,

I’m writing this blog post to clear up any confusion I may have given the community over my last blog post “Flex’s future :: A component developers take“.

It seems that some may judge a book by it’s cover and I never really liked that space in life. So here is the content of the book whose cover was read in that post.

I have worked with the Flash Platform in many incarnations. I have seen the Flex SDK from the beginning when it was the Flash component framework around Flash 6, to the AS2 version of the V2 component framework Macromedia released as an update to an otherwise sloppy AS1 prototyped component framework. The next evolution came with Flex. Flex used the component framework existing in Flash and built upon it, I saw that transition as well.

The moral of this story is there are many chapters to my book and the Flash Platform. My post came from a deep emotional issue of how Adobe so thoughtfully announced the reconfiguration of their company leaving developers like myself hanging from their bootstrap.

I have been told that the Flex SDK does have the “crap” I was talking about due to the conversion from AS2 and AS3, thus the UIComponent’s monolithic size. Plainly put, object creation was expensive in AS2, not so in AS3 but Adobe could not just switch everything to composition in a heart beat. I think any competent developer knows that even a refactoring might not take care of the bloat-design that is existent in the UIComponent.

So what to do?

Flex now called Apache Flex is being open-sourced and the community can change the direction of what it actually is, what it can be and how it can get there.

I’m honored to be selected as an initial commiter to the Flex SDK and will try hard to reinvent Flex in the language a lot of us hold dear to are heart, ActionScript.

My blog post did not at all mean I am throwing mud at Adobe or the Flex SDK, if you read my post again, I said these problems were there all along and nothing was done about them. This problem lead to the SDK not reaching it’s full agile potential in my opinion.

In closing

I love ActionScript and I love flex, when you commit a percentage of your life to something, you have a right to talk about, rant about it and laugh about it. To all those that read this, AIR is not dead on mobile and the Flex SDK can become an accessible cross platform development alternative.

For Flex-ActionScript, HTML5 and JavaScript, who knows what the innovative community can dream up, we will just have to wait and see.

Mike

Categories: announcements Tags:

AIR Mobile :: Flex MobileUI Toolkit 1 released

December 15th, 2011 Michael Schmalle No comments

Hi,

After months of development and research, Teoti Graphix, LLC has released the MobileUI Toolkit 1. Our first toolkit in a series of time saving AIR mobile Flex component toolkits.

The MobileUI Toolkit 1 focuses on;

  • A PopUp that is an inversion of control type manager decorating SkinnablePopUpCtontainer subclasses such as the Dialog and TextDialog.
  • An Alert API that uses static methods but is not at all tied to static methods for open and close, the PopUp class can even be extended.
  • An enhanced MobileButton that adds a longClick event and longClickDelay style.
  • A vertical and horizontal Picker component that is not based off of the List. This is important for memory and performance needs.
  • A simple ProgressBar component that allows for primary, secondary and indeterminate progress levels plus left and right layout directions.
  • A very powerful and skinnable/styleable RatingBar component that subclasses the ProgressBar.
  • A WebView component that wraps the StageWebView and adds UIComponent layout logic.
  • A SkinnableStageWebview that can be used to create composite WebView components with controls.
  • A WebViewBrowser that has actually implemented the SkinnableStageWebview with skinparts to make a simple OS browser.

This is a very highlevel description of what this toolkit offers. Teoti Graphix, LLC has been creating Flex components for a while now and knows how to create extensible component frameworks. You not only receive these finished polished components but have a place to jump off and create even more complicated components based off of the core framework.

The toolkit was designed in a way to promote extension by abstracting core classes in the PopUp framework and other various classes into a common library project in our development. This means as new toolkits are released they all will include the core components. For more information on this you can check out the Reference Book on our site and see what is contained in the UICommon kit.

Images

logo

I thought about posting them here, I had in a previous post but I’m sure if you are interested you can take a second and just check out the product page that has all this information condensed and outlined.

Product Page: Mobile UI Toolkit 1

Support

Our support is one on one answers and even helpful information. Just look at the wealth of information and dedication on this blog and you will get an idea of the commitment we put into our products. There is a technical forum that is available for all customer users.

Our reference book has a very good image and screenshot layout for fast and concise understanding.

Documentation

Our documentation is second to none. A lot of the documentation and asdocs are written well before the actual component is finished. Good documentation is clear communication and shows the true intent of the component and it’s capabilities. We do not want to sell products to people that don’t need what the product offers. Instead of spending time and money on fancy advertising and flashy adds, we invest time where it counts, documentation, examples and asdoc code comments.

Our ASDoc documentation;

SeeMobileUI Toolkit 1 ASDocs

The ASDoc documentation is created by our own hand written Java ActionScript Paser and Documentor JASDoc, using the one and only as3-commons-jasblocks framework! Yes that is right, that documentation in the above link is ALL created with our opensource as3-commons-jasblocks parsing framework with a custom Java application written for the documentor. Now here is a developer that really loves his ActionScript!

You may notice some interesting additions like implemented by, Host component links and more.

You will also notice that all the example packages that hold the product examples contain the source code and image! So you can quickly look at the image, scroll down to the source and see how it was implemented in MXML.

Conclusion

What you get by purchasing components by Teoti Graphix, LLC is supporting an experienced ActionScript Flex programmer and helping to push the community forward through this support. The components we offer are supported and feature requests are available, so when you purchase you have the option of asking for new things. The odds are, if your request is possible, it will probably get implemented, no red tape here.

Currently we are working with Android and have a proto application for viewing these components in an apk. If you are interested in this for viewing purposes please contact me (Contact Mike).

Also if there are a couple iOS users out there that like this component toolkit say with an iPad and iPhone, we are willing to give away a couple free licenses for testing the components in the iOS mobile devices. We mainly program Android and do not even have iOS developer licenses.

Thanks,

Mike

Flex’s future :: A component developers take

December 13th, 2011 Michael Schmalle 15 comments

Hi,

Reading some blog posts and other information about the Future of Flex, I am getting a clear image of the future. If Adobe hangs onto all run-times such as Flash Player, AIR and maintains their position that Flex is a money loser, Flex is dead.

Teoti Graphix, LLC has made decent money on 3rd party Flash and Flex components since 2004 and with Flash back to 2002. I just read the following in a great article;

The Fading of the Flex Framework

“If the 3rd party Flex component market never took off, why does Adobe think there is a large community willing to spend time (which equals money) doing what Adobe is no longer willing to do — fix and further the hot mess that is the Flex SDK?”

I belong to the 3rd party component market, no one ever talks to me. I have had quite large businesses contract flex components for their applications. See the thing is here, Adobe never cared about the 3rd party component developers. So to say that the market never took off is not accurate, the market never existed because Adobe didn’t see money in it for them.

I talked to Matt Chotin Adobe(when he still existed) many times about creating an ecosystem that extended the Flex framework through a component ecosystem and there by establishing good coding standards for components. The best Adobe came up with was the pitiful Flex Exchange which was and is a joke. It’s like a ghost town of outdated crap.

I have spent the last 3 months creating a mobile toolkit that offers some very useful mobile components for AIR applications. Does it make me sick to my stomach sometimes that companies(individuals) are willing to laugh at spending 149.99$ for 10 professional, documented and supported components? Not to mention have the ability to ask for new features from me. Get one on one support from a real person.

YES, see the joke is on those that didn’t pass their Math statistics class and can’t see the tree from the forest. Before developing software I was a Land Surveyor in the construction industry. You know the most valuable thing to a builder/contractor is their tools. They know spending more money on a good tool will save them twice as much money in the end. This is not BS spewed from my mouth, this is reality in industries that have been around for 1000′s of years, how long has the software industry been around? … Not even close to being a mature market place.

You see, Flex never got passed diapers in my eyes with the way developers approached it’s code. It was wam bam out the door who cares if it’s still dripping with crap. And hey, copy and paste that crap right into the next batch of crap, because in the end you have nothing but crap. The Flex SDK has a lot of crap supporting it and even inside it.

No, real component developers(I am talking software in general) care about their code and if anything is wrong will fix it. A component developer or as I like to put it, a tool developer cares about “his/her” niche in the grand ecosystem. This is why proprietary systems do work still because they “own” what they release and take pride in it (not like the freaking wasteland of dead flex code out there, yeah hey GO GREEN! The worlds dead open-source servers waste a HUGE amount of energy). With my components, I still give you the option to spend a little more and get all the source code.

For Flex to thrive in the next 5 years, the Spoon project MUST transform it’s image from the diaper wearing, over bloated non standard code dripping SDK that it is into something that is a respectable piece of software that solves a purpose and is not trying to be something it’s not (ehhem Flash dirty Catalyst).

Spoon NEEDs to create a 3rd party component ecosystem because those developers COULD give back to the SDK on a low level and being paid by there components on the other hand. (Like moi) But if they want to continue to devalue my skills as a tool dev, I’ll be on the next train as the city is nuked.

To answer one more statement;

“why does Adobe think there is a large community willing to spend time (which equals money) doing what Adobe is no longer willing to do”

There are real tool developers that could make a good living selling components. If this was the case I, like others can fill the shoes of many Adobe employes. With less red tape, 10 times more bug fixes and feature enhancements could be possible.

In closing

As I stand here with over 8 years of Flash and Flex experience, not one person from Adobe or Spoon has contacted me (yeah I volunteered and am on the mailing list). This is why Flex is dead because babies can’t communicate and are dependent on mama which is Adobe. In a way it actually makes me feel sad, as the outsider from Meredith New Hampshire that doesn’t get invited to the “party” this time. On the other hand it actually may be a sign from the Universe that Java Android UI components are respected/valued with ROI and that is my destiny.

We will see.

Mike

PS These opinions are mine and Teoti Graphix, LLC shares these opinions happily. I am what I am.

Categories: rants Tags: ,

AIR Mobile :: Hello Callout Style & Skin

December 12th, 2011 Michael Schmalle No comments

The Callout container pops up above application content when initiated by some type of user interaction or programmatic trigger. The Callout is a subclass of the SkinnablePopUpContainer which implements the open() and close() aspects of the Callout container.

The Callout can be modal open(owner, true) or non modal open(owner, false).

What Is The Callout

The Callout is a SkinnablePopUpContainer that implements custom logic for the following;

  • The callout’s arrowDirectionArrowDirection.RIGHT, ArrowDirection.UP, ArrowDirection.LEFT, ArrowDirection.DOWN, ArrowDirection.NONE

Styling The Callout

contentBackgroundAppearance

The contentBackgroundAppearance style of the Callout allows the visual appearance of the contentGroup to be framed by an inset, flat or none border.

NOTE: The red Rect background is to show the bounds of the contentGroup. Use the backgroundColor and backgroundAlpha to actually set the color of the background, you don’t add the Rect like I have below, it’s for explanation only.

inset

Note the beveled white border and top inset shadow on top of the contentGroup.

flat

Note the bevel is gone and the contentGroup is still masked by the cornerRadius of the Callout skin.

none

Note the inset and mask is not present, the contentGroup is displayed without any border frame.

Skinning The Callout

The Callout component uses the CalloutSkin class to create it’s skin parts based off of the MobileSkin. Skins based off the MobileSkin are a bit more complicated for new developers to wrap their heads around since they don’t follow the Spark MXML pattern for creating skins. The Callout skin is adjustable by creating a subclass and setting protected property values.

Protected Properties that can be adjusted

  • dropShadowVisible:Boolean – Whether the drop shadow of the Callout is visible.
  • useBackgroundGradient:Boolean – Whether the Callout adjusts the background gradient by a 15% lighten and 60% darken algorithm.
    • This brightness adjustment affects the backgroundColor style when set.
  • contentCornerRadius:uint – Adjusts the corner radius of the contentBackgroundColor style mask mentioned above.
    • This property only applies to the inset and flat contentBackgroundAppearance style value.
  • contentBackgroundInsetClass:Class – The Class used to render the inset and drop shadow show in the inset image above.
    • Default – spark.skins.mobile*.assets.CalloutContentBackground – this is an FXG asset.
  • backgroundCornerRadius:Number – The corner radius of the backgroundColor style fill.
  • frameThickness:Number – The thickness of the backgroundColor frame.
    • This is comparable to the contentGroup's padding from the edge of the Callout.
  • borderColor:Number – The stroke color of the backgroundColor fill.
  • borderThickness:Number – The thickness of the backgroundColor border frame.
  • arrowWidth:Number – The width of the arrow skin part in the vertical direction and the height of the arrow skin part in the horizontal direction.
  • arrowHeight:Number – The height of the arrow skin part in the horizontal direction and the width of the arrow skin part in the vertical direction.

A simple MyCalloutSkin override

In the code below, the non commented lines are the protected variables of the subclass that are affecting the MyCalloutSkin skin.

MXML

<s:Callout>
	<s:Rect width="100%" height="100%">
		<s:fill>
			<s:SolidColor color="#FF0000"/>
		</s:fill>
	</s:Rect>
	<s:VGroup paddingTop="5" paddingRight="5" paddingBottom="5" paddingLeft="5">
		<s:Label text="contentGroup"/>
	</s:VGroup>
</s:Callout>

CSS

s|Callout {
	contentBackgroundAppearance:none;
	skinClass:ClassReference("skins.MyCalloutSkin");
}

skins.MyCalloutSkin

package skins
{
 
import spark.skins.mobile.CalloutSkin;
 
public class MyCalloutSkin extends CalloutSkin
{
	public function MyCalloutSkin()
	{
		super();
 
		// assuming a 160 DPI for simplicity
		dropShadowVisible = false;
		useBackgroundGradient = false;
		//contentCornerRadius = 0;
		//contentBackgroundInsetClass = null;
		//backgroundCornerRadius = 20;
		frameThickness = 50;
		borderColor = 0xFFCC00;
		borderThickness = 10;
		arrowHeight = 15;
		//arrowWidth = 10;
	}
}
}

 

A simple MyCalloutSkin override of inset

In the code below, the non commented lines are the protected variables of the subclass that are affecting the MyCalloutSkin skin with an inset contentBackgroundAppearance style.

CSS

s|Callout {
	contentBackgroundAppearance:inset;
	skinClass:ClassReference("skins.MyCalloutSkin");
}

skins.MyCalloutSkin

package skins
{
 
import spark.skins.mobile.CalloutSkin;
 
public class MyCalloutSkin extends CalloutSkin
{
	public function MyCalloutSkin()
	{
		super();
 
		// assuming a 160 DPI for simplicity
		dropShadowVisible = false;
		useBackgroundGradient = true;
		//contentCornerRadius = 0;
		//contentBackgroundInsetClass = null;
		backgroundCornerRadius = 0;
		frameThickness = 50;
		borderColor = 0xFFCC00;
		borderThickness = 5;
		arrowHeight = 30;
		//arrowWidth = 10;
	}
}
}

Note:

  • The useBackgroundGradient property is now true.
  • The backgroundCornerRadius property is set to 0.
  • The borderThickness property is now set to 5.
  • The arrowHeight property is now set to 30.

You will also notice that the contentGroup has an inset border above it with a white border. This is the FXG asset mentioned above. The contentCornerRadius property relates to the actual corner radius used IN the FXG asset. The contentCornerRadius property matches the backgroundColor style’s inset mask to the DPI dependent FXG asset’s corner radius so the skin correctly masks the FXG inset resolution used.

Skinning the contentBackgroundInsetClass

You may be wondering if the FXG inset graphic is skinnable and the answer is yes. If you are new to skinning or FXG you would not be aware that FXG is compiled to native graphics and becomes a SpriteVisualElement during runtime. This means that any SpriteVisualElement can replace the default contentBackgroundInsetClass. Also note that if you choose to replace this class with your own implementation, you will need to supply DPI dependent versions if you plan on creating a DPI independent application.

CalloutInset.fxg

<Graphic version="2.0" xmlns="http://ns.adobe.com/fxg/2008"
	scaleGridLeft="6" scaleGridRight="294" 
	scaleGridTop="15" scaleGridBottom="194">
 
	<!-- invisible fix for scaling -->
	<Rect x="0" y="199" width="300" height="1">
		<fill>
			<SolidColor color="#ffffff" alpha="0"/>
		</fill>
	</Rect>
 
	<!-- Content Shading Top -->
	<Rect x="0" y="0" width="300" height="10"
			topLeftRadiusX="0" topLeftRadiusY="0"
			topRightRadiusX="0" topRightRadiusY="0">
		<fill>
			<LinearGradient rotation="90">
				<GradientEntry ratio="0" color="#000000" alpha="0.6"/>
				<GradientEntry ratio="0.5" color="#000000" alpha="0"/>
			</LinearGradient>
		</fill>
	</Rect>
 
	<!-- Content Highlight -->
	<Rect x="0.5" y="0.5" width="299" height="199" radiusX="0" radiusY="0">
		<stroke>
			<SolidColorStroke color="#FFCC00" alpha="0.8"	weight="2"/>
		</stroke>
	</Rect>
</Graphic>

skins.MyCalloutSkin

package skins
{
 
import spark.skins.mobile.CalloutSkin;
 
public class MyCalloutSkin extends CalloutSkin
{
	public function MyCalloutSkin()
	{
		super();
 
		// assuming a 160 DPI for simplicity
		dropShadowVisible = false;
		useBackgroundGradient = true;
		contentCornerRadius = 0;
		contentBackgroundInsetClass = CalloutInset;
		backgroundCornerRadius = 0;
		frameThickness = 50;
		borderColor = 0xFFCC00;
		borderThickness = 5;
		arrowHeight = 30;
		//arrowWidth = 10;
	}
}
}

Note that we now use the contentCornerRadius property to match up with the FXG radii which are now 0. The contentBackgroundInsetClass property is set to CalloutInset and the inset will now be used instead of the default defined in CalloutSkin.

Using a PNG background skin

Although the example below is rough and does not use 9 scale slicing, it does show that creating Bitmap backgrounds for the Callout is pretty simple based on what you want.

To get proper scaling and 9 scale, there is a little more work involved not covered in this example. Also, there might be logic that determines what png to use based on the arrow layout.

skins.MyCalloutSkin

package skins
{
 
import assets.CalloutInset;
 
import flash.display.DisplayObject;
 
import spark.skins.mobile.CalloutSkin;
 
public class MyCalloutSkin extends CalloutSkin
{
	[Embed(source="/assets/callout-background.png",
			scaleGridTop="44", scaleGridRight="85", scaleGridBottom="47", scaleGridLeft="16")]
	private var backgroundClass:Class;
 
	private var background:Object;
 
	public function MyCalloutSkin()
	{
		super();
 
		// assuming a 160 DPI for simplicity
		dropShadowVisible = false;
		useBackgroundGradient = true;
		contentCornerRadius = 0;
		contentBackgroundInsetClass = CalloutInset;
		backgroundCornerRadius = 0;
		frameThickness = 10;
		borderColor = 0xFFCC00;
		borderThickness = 0;
		//arrowHeight = 30;
		//arrowWidth = 10;
	}
 
	override protected function createChildren():void
	{
		// put the background behind everything
		background = new backgroundClass();
		addChild(DisplayObject(background));
 
		super.createChildren();
	}
 
	override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
	{
		// create a simple png background using the superclass's layout frame logic
		var showBorder:Boolean = !isNaN(borderThickness);
		var borderWeight:Number = showBorder ? borderThickness : 0;
 
		// calculate the frame which the Bitmap will be positioned and sized to
		var frameX:Number = Math.floor(contentGroup.getLayoutBoundsX() - frameThickness) - (borderWeight / 2);
		var frameY:Number = Math.floor(contentGroup.getLayoutBoundsY() - frameThickness) - (borderWeight / 2);
		var frameWidth:Number = contentGroup.getLayoutBoundsWidth() + (frameThickness * 2) + borderWeight;
		var frameHeight:Number = contentGroup.getLayoutBoundsHeight() + (frameThickness * 2) + borderWeight;
 
		background.x = frameX;
		background.y = frameY;
		background.width = frameWidth
		background.height = frameHeight;
	}
}
}

As you can see the above image square is the callout-background.png and the Bitmap is sized and placed behind all layout assets.

Conclusion

The Callout component it quite easy to style basic. The styling gets more invloved when you want more dynamic styling than the inset background or any type of background that is not a gradient or stroked fill. I might actually set out to make a skin that is a little more user friendly for those that are looking to style with abit more CSS and are not to concerned about the impact of their application, for example maybe a tablet application.

Part 2 will focus more on the CalloutArrow placements, skinning and the CalloutButton implementation.

About the Author

Michael Schmalle has been developing Adobe Flex and the Flash Player since Flash version 5 (2002). He has numerous open source projects in ActionScript3 (including an ActionScript3 parser/lexer DOM for reading and writing AS3 source code) and Flex (user interface components). He has also been an active participant in the Flex community (just goolge him or Teoti Graphix, LLC) since 2004. He also realizes technologies change and is actively developing user interface components and applications on the Google Android mobile platform.

See Teoti Graphix. LLC.

GIT: https://github.com/teotigraphix

Twitter: http://twitter.com/TeotiGraphix/

Categories: AIR Mobile Tags: ,

AIR Mobile :: Hello BusyIndicator take 2

December 5th, 2011 Michael Schmalle 2 comments

This article is Take 2 on the last article discussing the BusyIndicator.

"A good component developer breaks things into pieces, smashing them on the floor, putting the parts back into classes" ;-)

See Air Mobile :: Hello BusyIndicator take 1

What Needs To Be Fixed

  • Ditch the BusyPopUpSkin and use a special curcumstance partAdded() implementation for adding skinparts.
  • Move popup layout logic to custom component class.
  • Add ability to notify user of updates through a status interface on the component.

The new component;

Note: These articles you read of mine are going to show you the things that a lot of tutorials don’t. I have years of experience making components and know one thing, do what your heart tells you to do, not what the book says. You need experience, but once you have it, walk your own path and make it work the way it should not how it is supposed to work. :)

Let’s start off by looking at the BusyLabelPopUp custom component’s code; (yes read it before continuing)

package components
{
 
import flash.geom.Point;
 
import spark.components.BusyIndicator;
import spark.components.Label;
import spark.components.SkinnablePopUpContainer;
import spark.layouts.HorizontalAlign;
import spark.layouts.VerticalAlign;
import spark.layouts.VerticalLayout;
 
/**
 * A PopUp that contains a BusyIndicator and Label for status updates.
 * 
 * @author Michael Schmalle
 * @copyright Teoti Graphix, LLC
 * @productversion 1.0
 */
public class BusyLabelPopUp extends SkinnablePopUpContainer
{
	//--------------------------------------------------------------------------
	// 
	//  SkinPart :: Variables
	// 
	//--------------------------------------------------------------------------
 
	//----------------------------------
	//  busyIndicator
	//----------------------------------
 
	[SkinPart(required="false")]
 
	/**
	 * The busy indicator that notifies the user of indeterminate progress.
	 */
	public var busyIndicator:BusyIndicator;
 
	//----------------------------------
	//  statusDisplay
	//----------------------------------
 
	[SkinPart(required="false")]
 
	/**
	 * The Label that will display the status message if any.
	 */
	public var statusDisplay:Label;
 
	//--------------------------------------------------------------------------
	// 
	//  Public :: Properties
	// 
	//--------------------------------------------------------------------------
 
	//----------------------------------
	//  status
	//----------------------------------
 
	/**
	 * @private
	 */
	private var statusChanged:Boolean = false;
 
	/**
	 * @private
	 */
	private var _status:String;
 
	/**
	 * Sets the status message on the popup.
	 */
	public function get status():String
	{
		return _status;
	}
 
	/**
	 * @private
	 */
	public function set status(value:String):void
	{
		if (_status == value)
			return;
 
		_status = value;
 
		statusChanged = true;
		invalidateProperties();
	}
 
	//--------------------------------------------------------------------------
	// 
	//  Constructor
	// 
	//--------------------------------------------------------------------------
 
	/**
	 * Constructor.
	 */
	public function BusyLabelPopUp()
	{
		super();
	}
 
	//--------------------------------------------------------------------------
	// 
	//  Overridden Public :: Methods
	// 
	//--------------------------------------------------------------------------
 
	override public function updatePopUpPosition():void
	{
		// use the owner x, y coords
		var point:Point = new Point(owner.x, owner.y);
		// convert the owner x,y to global so this can be laid out in 
		// nested Views
		point = owner.parent.localToGlobal(point);
		// set the popup's global x,y coords
		x = point.x;
		y = point.y;
		// mirror the owner's width and height onto the popup
		width = owner.width;
		height = owner.height;
	}
 
	//--------------------------------------------------------------------------
	// 
	//  Overridden Protected :: Methods
	// 
	//--------------------------------------------------------------------------
 
	override protected function partAdded(partName:String, instance:Object):void
	{
		super.partAdded(partName, instance);
 
		if (instance == contentGroup)
		{
			// if the contentGroup has 0 children right now, we know 
			// a custom skin was not applied and we should create the 
			// skinparts programatically
			// this is being 'polite' to future devs that may need an
			// MXML skin implementation adding skinparts declarativly
			if (contentGroup.numElements == 0)
			{
				// update layout knowing we are adding composite skinparts
				updateLayout();
				// create the busyIndicator skinpart
				createBusyIndicator();
				// create the statusDisplay skinpart
				createStatusDisplay();
			}
		}
	}
 
	override protected function commitProperties():void
	{
		super.commitProperties();
 
		if (statusChanged)
		{
			// this is optional but smart, create a commit method so your
			// devs that follow have a hook to change your code down the road
			commitStatus();
			statusChanged = false;
		}
	}
 
	//--------------------------------------------------------------------------
	// 
	//  Protected :: Methods
	// 
	//--------------------------------------------------------------------------
 
	protected function updateLayout():void
	{
		// create a nice and simple VerticalLayout that centers both parts
		// in the full layout. Remeber that the skin sets all layout
		// constraints to 0, effectively saying width=100%, height=100%
		var vlayout:VerticalLayout = new VerticalLayout();
		vlayout.horizontalAlign = HorizontalAlign.CENTER;
		vlayout.verticalAlign = VerticalAlign.MIDDLE;
		vlayout.gap = 10;
		layout = vlayout;
	}
 
	protected function createBusyIndicator():void
	{
		// this could also be a factory, for simplicity we create here
		// this is really no different than what the mobile skins do
		busyIndicator = new BusyIndicator();
		// setting the id allows CSS #busyIndicator
		busyIndicator.id = "busyIndicator";
		contentGroup.addElement(busyIndicator);
	}
 
	protected function createStatusDisplay():void
	{
		// this could also be a factory, for simplicity we create here
		// this is really no different than what the mobile skins do
		statusDisplay = new Label();
		// setting the id allows CSS #statusDisplay
		statusDisplay.id = "statusDisplay";
		contentGroup.addElement(statusDisplay);
	}
 
	protected function commitStatus():void
	{
		if (!statusDisplay)
			return;
		// update the status text to show on the user interface
		statusDisplay.text = status;
	}
}
}

Was All This Code Worth It

Yes, you are looking at a good abstraction of a user interface component that displays a BusyIndicator and Label. This class could be reused, subclassed and skinned. This is the ultimate sunny day for an application developer trust me. Most of the time I see good developers just not wanting to take the time to write good solid component code. This is also where we will get into the eternal fight of unit testing verses refactoring. I guess it comes down to whoever wins the race right? I am confident I will win with the way I write my components, are you confident in your user interface component code (oh you don’t have any reusable components)?

Creating the API

One of the first things I do is break down what is the external (public) communication to this component. Basically we have one thing, the status message. I mentioned in the previous article that the BusyIndicator is basically private meaning locked doors, there is nothing to expose with it. The styles are already there to access with CSS.

Creating the User Interface blocks

The blocks of a component in the Spark framework are skinparts. We know we needed a BusyIndicator, that is busyIndicator skin part. We also know we need a way to express the status text. For simplicity we use the Label that can display single and multiline text. For that we create the statusDisplay skin part.

SkinPart Addition

Here is the controversial part of this article. I am not creating a skin for this component. We actually create the skin parts in the BusyLabelPopUp.

  • We honor the spark skin contract by checking the numElements of the contentGroup so we don’t add composites if they are already there.
  • We create a new vertical layout that will size correctly and center the busyIndicator and statusDisplay.
    • Remember the layout of the SkinnablePopUpContainer is proxied to the contentGroup.
  • We create two hook methods for the creation of the busyIndicator and statusDisplay.
    • This allows for subclass overrides, remember protected in a well designed component is good karma.
  • When creating skinparts in ActionScript, remember to set the id, if you don’t you cannot style them from id selectors in CSS.

Property Commital

Understanding the invalidation passes of a UIComponent is very important. If you get this right, Flex components are very fast. A lot of the times developers curse the Flex framework for it’s bottlenecks in rendering. The sad truth is about 80% of the time it’s those very developers that are creating the bottlenecks with their code.

commitProperties()

The standard property change algorithm is;

  • Check to see if the property has changed.
  • Set a backing variable usually private.
  • Switch a flag that will be picked up in commitProperties()
  • Call invalidateProperties() to trigger commitProperties() on the next frame update.
  • If the property is Bindable, call dispatchEvent(new Event("propertyChanged"))

Once the status property has changed, a frame will pass and commitProperties() will fire. During this method call, if the statusChanged flag is true, commitStatus() will be called and the statusDisplay.text will be updated with the new text.

Note: There is also a pattern where the statusDisplay.text gets called directly in the setter. This has to do with the sync between parent and child. In this example it really dosn’t matter and the commit hook method allows for future adjustment very easily.

PopUp Position And Layout

The layout and position logice we taken out of the view and the SkinnablePopUpContainer has a nice public method that can AND should be overridden; updatePopUpPosition().

In this method we convert the owner‘s point, in the case of the example it’s a View into gloabl coords and apply those x and y values to the popup.

The Updated View Code

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
		xmlns:s="library://ns.adobe.com/flex/spark" 
		title="Take2">
 
	<fx:Script>
		<![CDATA[
	import components.BusyLabelPopUp;
 
	private var mTimer:Timer;
 
	private var mPopUp:BusyLabelPopUp;
 
	private var mCount:int = 0;
 
	protected function button1_clickHandler(event:MouseEvent):void
	{
		// if busy, return
		if (mPopUp)
			return;
 
		mCount = 0;
		createPopUp();
		startOperation();
		updateStatus("Loading...");
	}
 
	private function createPopUp():void
	{
		mPopUp = new BusyLabelPopUp();
		mPopUp.open(this);
	}
 
	//--------------------------------------------------------------------------
	// 
	//  Bellow is just Application logic now
	// 
	//--------------------------------------------------------------------------
 
	private function startOperation():void
	{
		mTimer = new Timer(1000);
		mTimer.addEventListener(TimerEvent.TIMER, timerHandler);
		mTimer.start();
	}
 
	private function endOperation():void
	{
		mPopUp.close();
		mPopUp = null;
	}
 
	private function updateStatus(message:String):void
	{
		mPopUp.status = message;
	}
 
	private function timerHandler(event:TimerEvent):void
	{
		updateStatus("Loading... " + mCount++);
 
		if (mCount == 4)
		{
			mTimer.removeEventListener(TimerEvent.TIMER, timerHandler);
			mTimer = null;
			endOperation();
		}
	}
 
		]]>
	</fx:Script>
 
	<s:layout>
		<s:VerticalLayout horizontalAlign="center" paddingTop="50"/>
	</s:layout>
 
	<s:actionContent>
		<s:Button id="initiateButton"
				  label="Set Busy" 
				  click="button1_clickHandler(event)"/>
	</s:actionContent>
 
	<!-- This button will not be touchable when the indicator is present -->
	<s:Button label="Can't touch this! :)"/>
 
</s:View>

In the code above;

  • Removed all popup logic and layout.
  • Create the BusyLabelPopUp and call open().
  • Create a fake operation that loops 4 times to demonstrate the dynamic status update of the busy overlay.
  • There are only a couple lines of code in the above file that actually have to do with the new component, the rest is application logic.

Styling The PopUp

Now that the PopUp is in a custom component we have gained the ability to control the styles from the outside of ALL skin parts. Here is the application styling that targets our new skinparts of the BusyLabelPopUp component.

@namespace s "library://ns.adobe.com/flex/spark";
@namespace components "components.*";
 
components|BusyLabelPopUp {
	backgroundAlpha:0.3;
	backgroundColor:#000000;
}
 
components|BusyLabelPopUp #busyIndicator {
	symbolColor:#FFFFFF;
	rotationInterval:10;
}
 
components|BusyLabelPopUp #statusDisplay {
	fontWeight:bold;
	color:#FFFFFF;
}

Conclusion

This Take 2 was really a tagent article I took talking about component development. It provided a good example of the two challenges that face application development; Speed verses Reusablity.

If you are developing mobile applications, think about components and what they can do for you. Along that note Teoti Graphix, LLC has a new mobile toolkit coming out and 3 more in the making;

Check out;

About the Author

Michael Schmalle has been developing Adobe Flex and the Flash Player since Flash version 5 (2002). He has numerous open source projects in ActionScript3 (including an ActionScript3 parser/lexer DOM for reading and writing AS3 source code) and Flex (user interface components). He has also been an active participant in the Flex community (just goolge him or Teoti Graphix, LLC) since 2004. He also realizes technologies change and is actively developing user interface components and applications on the Google Android mobile platform.

See Teoti Graphix. LLC.

GIT: https://github.com/teotigraphix

Twitter: http://twitter.com/TeotiGraphix/

Categories: AIR Mobile Tags: ,

Air Mobile :: Hello BusyIndicator take 1

December 5th, 2011 Michael Schmalle No comments

The BusyIndicator defines a component to display when a long-running operation is in progress.

What is the BusyIndicator

The BusyIndicator is a UIComponent that plays an animation while a background operation is running to alert the user of indeterminate progress. The BusyIndicator by default draws twelve spokes that set each spoke’s alpha in intervals of about 0.1 foreach rotation interval. This gives the illusion that the indicator is spinning.

Metrics

  • 160 DPI – 26×26 pixels
  • 240 DPI 40×40 pixels
  • 320 DPI 52×52 pixels

It’s important to note that the above dimensions are measured. If the width and height are increased or decreased, the component will fill the minimum of the two.

What Is The BusyIndicator Used For

As mentioned, the BusyIndicator is used to notify the user of a long running operation. This component due to the way it was programmed is not very "extendable". Most of the internal methods are private or mx_internal meaning as a responsible developer you cannot even override the draw logic without opening up the mx_internal namespace.

The BusyIndicator could be used in a modal PopUpContainer to disallow user interaction while the operation is in progress. The BusyIndicator could be placed within the ActionBar to notify the user in a less obtrusive nature. The BusyIndicator could just be placed on top of ViewNavigator View instances to act as a non interuptive progress targeting the View that is loading data.

With either of the options listed above it’s important to note that the BusyIndicator is just a plain old UIComponent under the covers. This means it’s a standard display object that can be placed where ever needed.

How to Sart And Stop The Rotation

Starting and stopping the rotation is out of the hands of the developer. The component listens for ADDED_TO_STAGE and REMOVED_FROM_STAGE events to start and stop it’s animation.

How To Style The BusyIndicator

The BusyIndicator has two styles;

  • rotationInterval:Number – In milliseconds that amount of relative spin given to the indicator.
  • symbolColor:uint – The color of the indicator’s spokes.

Getting Started with The With The BusyIndicator :: Take1

To start using the BusyIndicator, it’s as easy as placing the component in MXML or instantiating the component and adding it to the display list through ActionScript. Since the docs talk about that lets try some other strategies and see what we come up with.

Take 1 involves a newer developers take on the "touted" Spark skinning system and hey "just skin it!" attitude. The problem with skinning a component like the SkinnablePopUpContainer is the fact the default skin has 110 lines of MXML code in it that we copy.

Note: It is assumed with the plethora of mobile tutorials out there that you know how to create Flex Mobile projects and understand how to create custom components.

Step 1: Create a new mobile application

  • Create and setup a new Flex Mobile Project using the View-Based Application template: HelloBusyIndicatior
    • Name the view Take1

Step 2: Create a new SkinnablePopUpContainer skin

  • Create a new MXML Skin named BusyPopUpSkin
    • File > New > MXML Skin
  • Fill in the inputs as listed below

create mxml skin

  • With the BusyPopUpSkin.mxml open add the BusyIndicator component to the contentGroup
...
<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" minWidth="0" minHeight="0">
    <s:layout>
        <s:BasicLayout/>
    </s:layout>
	<s:BusyIndicator id="busyIndicator" verticalCenter="0" horizontalCenter="0"/>
</s:Group>
...

What we have done here is added the indicator to the content of the SkinnablePopUpContainer so when it is created, the BusyIndicator is automtaically running and centered within the popup.

Step 3: Create the code that will use the PopUp

  • Go back to the Take1.mxml View and replace the code with the following
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
		xmlns:s="library://ns.adobe.com/flex/spark" 
		title="Take1">
 
	<fx:Script>
 
	import skins.BusyPopUpSkin;
 
	import spark.components.SkinnablePopUpContainer;
 
	private var mTimer:Timer;
 
	private var mPopUp:SkinnablePopUpContainer;
 
	protected function button1_clickHandler(event:MouseEvent):void
	{
		// if busy, return
		if (mPopUp)
			return;
 
		createPopUp();
		startOperation();
	}
 
	private function createPopUp():void
	{
		// create the SkinnablePopUpContainer
		mPopUp = new SkinnablePopUpContainer();
		// set the styles
		mPopUp.setStyle("skinClass", BusyPopUpSkin);
		mPopUp.setStyle("backgroundColor", 0x000000);
		mPopUp.setStyle("backgroundAlpha", 0.3);
 
		layoutPopUp();
 
		// call PopUpManger to open and add
		mPopUp.open(this);
 
		positionPopUp();
	}
 
	private function layoutPopUp():void
	{
		// match the popups width, height to the View
		mPopUp.width = width;
		mPopUp.height = height;
	}
 
	private function positionPopUp():void
	{
		// use the View x, y coords
		var point:Point = new Point(x, y);
		// convert the View x,y to global so this can be laid out in nested Views
		point = parent.localToGlobal(point);
		// set the popup's global x,y coords
		mPopUp.x = point.x;
		mPopUp.y = point.y;
	}
 
	private function startOperation():void
	{
		mTimer = new Timer(3000, 1);
		mTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timerCompleteHandler);
		mTimer.start();
	}
 
	private function endOperation():void
	{
		mPopUp.close();
		mPopUp = null;
	}
 
	private function timerCompleteHandler(event:TimerEvent):void
	{
		mTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, timerCompleteHandler);
		mTimer = null;
		endOperation();
	}
 
 
	</fx:Script>
 
	<s:layout>
		<s:VerticalLayout horizontalAlign="center" paddingTop="50"/>
	</s:layout>
 
	<s:actionContent>
		<s:Button id="initiateButton"
				  label="Set Busy" 
				  click="button1_clickHandler(event)"/>
	</s:actionContent>
 
	<!-- This button will not be touchable when the indicator is present -->
	<s:Button label="Can't touch this! :)"/>
 
</s:View>

Whats going on in that code?

  • A Button was added to the actionContent of the ActionBar to trigger the creation of the popup.
  • A handler was added to create the popup and start the progress operation.
  • The createPopUp() method creates an new SkinnablePopUpContainer and sets it’s skinClass, this is how the skin is applied in this version.
    • The backgroundColor and backgroundAlpha styles are there to show how to adjust the popups background.
  • The layoutPopUp() assigns a new width and height based on the View's width and height.
  • The popup is then opened using the open() method that calls the PopUpManager.
  • The positionPopUp() method takes the View's x, y coords and translates them to global coords so the popup will be placed directly on top of the View.
    • This in effect creates a poor mans modal over the View.
  • The startOperation() method simulates a long running operation that in this case runs three seconds and calls the popups close() to dismiss the popup.

Step 4: Run the application

Conclusion

Well, looks the the BusyIndicator is a capable little component of display a familiar interface to mobile users. Do you see anything wrong with Take 1 of the BusyPopUp ?

I do and here are my thoughts;

  • Using a skin for this implementation is not good. Spaghetti code for 1 line of added content.
  • All of the logic for the popup is in a View class, no good, remember separation of duties in design patterns 101?
  • There is no way of adding any type of textual information to let the user know what is going on. (yes we could have easily put a Label in the contentGroup, how to get to it?)

What to do about this;

  • Take 2 will consist of a component developers implementation on solving the above problems.
  • Create a BusyLabelPopUp component that subclasses SkinnablePopUpContainer.
    • This will remove all logic from the view.
  • Use the partAdded() method of the new component to add a BusyIndicator and Label component to the contentGroup.
    • This will remove the need for duplicating the skin when in this case there is really no need for a custom skin.
  • Add a property status on the new component so real time textual updates are possible through the BusyLabelPopUp public interface.
  • Override the updatePopUpPosition() of the BusyLabelPopUp to apply the layout logic of the popup over the owner.

I went out of my way to make a crappy implementation first, so you can learn from the worst. :) In these new times of mobile, applications need to be abstract and decoupled because the likelihood of wanting to reuse code and components increase by a factor of 100.

Take 2 will be published shortly showing the proper creation of components and api.

About the Author

Michael Schmalle has been developing Adobe Flex and the Flash Player since Flash version 5 (2002). He has numerous open source projects in ActionScript3 (including an ActionScript3 parser/lexer DOM for reading and writing AS3 source code) and Flex (user interface components). He has also been an active participant in the Flex community (just goolge him or Teoti Graphix, LLC) since 2004. He also realizes technologies change and is actively developing user interface components and applications on the Google Android mobile platform.

See Teoti Graphix. LLC.

GIT: https://github.com/teotigraphix

Twitter: http://twitter.com/TeotiGraphix/

Categories: AIR Mobile Tags: ,

AIR Mobile :: Hello ActionBar take 1

December 2nd, 2011 Michael Schmalle No comments

The ActionBar class defines a component that includes title, navigation, and action content groups. The ActionBar control provides a standard area for navigation and action controls. It lets you define global controls that can be used from anywhere in the application, or controls specific to a view.

What Is The ActionBar

The ActionBar is a SkinnableComponent that contains a titleGroup, navigationGroup and actionGroup. Each of these Groups are populated by using their content properties titleContent, navigationContent and actionContent.

navigationGroup

The navigationGroup provides a consistent placement to the right of the titleGroup for application navigation buttons. When implementing an ActionBar in a mobile application it really comes down to the needs and feel of the application in question. The ActionBar was pretty much born out of a visual design pattern for consistency and user familiratity.

Think of the browser, something most people use almost everyday. This is an ActionBar for the desktop. You have the Back button navigation on the left, the url title in the middle and action items such as search on the right. The navigation items are usually global to the application and sometimes to the View itself.

There are three ways to add items to a navigationGroup;

  • Use the navigationContent Array on the View or ViewNavigator declarativly through MXML.
    • This allows the least flexibility.
  • Use the navigationContent property on the View or ViewNavigator.
    • This allows the View to properly fire property change events and change state.
  • Use ActionScript to add items through the IVisualElementContainer interface.
    • This allows fine grained control of the display list without thinking about what already exists in the navigationContent.
    • Not recomended but possible.

navigationContent MXML Example:

<s:navigationContent>
    <s:Button icon=@Embed(source='/assets/home_icon.png')
              click="dispatchEvent(new Event('homeClick'))"/>
</s:navigationContent>

ActionScript navigationContent Example (inside a View):

// create a new button
var element:Button = new Button();
element.label = "New Button";
// set the new content
navigationContent = [element];

ActionScript display list Example (inside a View):

// get the actionBar from the parent navigator
var actionBar:ActionBar = navigator.actionBar;
// remove all elements from the navigationGroup
actionBar.navigationGroup.removeAllElements();
// create a new button
var element:Button = new Button();
element.label = "New Button";
// ... add handlers etc
// add the button to the navigationGroup
actionBar.navigationGroup.addElement(element);

Note: Using actionscript means you are bypassing the built in mechanism of navigatorContent declarativly to add items from the navigationGroup. This is sometimes needed for dynamically updating the ActionBar's navigation because something about the applications state changed relative to what was initially implemented. Or you are using an application framework with mediators or commands.

titleGroup

The titleGroup is the exception to the above rule when using the ActionBar‘s content properties. The ActionBar title property when set creates a titleDisplay that is placed inside the titleGroup created in the ActionBarSkin. When a title String is not set on the ActionBar or parent IViewNavigator, the titleGroup is still created. The default titleDisplay component the skin creates is an internal TitleDisplayComponent that wraps two StyleableTextField components to create a title shadow effect.

You may be wondering why the titleDisplay is created when you can set the titleContent of the ActionBar. The above functionality allows for a default implemetation of the title property. Instead of having to put a Label inside the titleGroup every time you use the ActionBar, by default the title will be placed in the titleDisplay created in ActionBarSkin.createChildren().

Style the titleDisplay

s|ActionBar #titleDisplay {
	color:#F7F7F7;
	textShadowAlpha:1;
}

Note: To use a TypeSelector such as s|ActionBar, you must define these from within the main application’s css or external css file.

actionGroup

The actionGroup provides a consistent placement to the full right that define actions the user can take in a view. As mentioned witht the navagationGroup, the actionGroup will contain items such as a search button or even an overflow action menu.

The actionGroup uses the same pattern for population as the navigationGroup(see above). The actionContent Array will be used to assign controls to the actionGroup instance.

Layouts

The navigationGroup and actionGroup also have sibling properties in navigationLayout and actionLayout. These added properties allow the developer to target specific padding, gaps and alignment for each group. Not adding these proxied properties in the ActionBar would mean you would have to set a new Group for each content if you wanted to change any of the charateristics of their layouts.

What Is The ActionBar Used For

The ActionBar is used for a consistent placement of title, navigation and actions. The component also very closely follows the existing ActionBar user interface pattern defined by most mobile OSs and browsers.

What Is The ActionBarSkin

The ActionBarSkin is an actionscript class that creates the ActionBar‘s skin parts, border and paints the background gradient.

SkinParts

  • navigationGroup:Group – defines the appearance of the navigation area of the component.
  • titleGroup:Group – defines the appearance of the title area of the component.
  • titleDisplay:IDisplayText – defines the appearance of the title text in the component.
  • actionGroup:Group – defines the appearance of the action area of the component.

Styles

How to style the default ActionBarSkin;

  • Use the chormeColor style to set the backgrounds gradient color.
  • Use the backgroundAlpha style to set the background gradient transparency.
  • Use the padding styles to offset all content Groups.
s|ActionBar {
	chromeColor:#3399FF;
	backgroundAlpha:0.4;
}

Custom skin

To illustrate how to skin these archaic mobile skins lets say we want our own gradient and botom border.

package skins
{
 
import flash.display.GradientType;
import flash.geom.Matrix;
 
import spark.skins.mobile.ActionBarSkin;
 
public class MyActionBarSkin extends ActionBarSkin
{
	private static var colorMatrix:Matrix = new Matrix();
 
	private var mFillColors:Array = [0xCCCCCC, 0xFFFFFF, 0xBCBCBC];
	private var mFillAlphas:Array = [1, 1, 1];
	private var mFillRatios:Array = [0, 50, 255];
	private var mLineColor:uint = 0x333333;
	private var mLineWeight:int = 2;
 
	public function MyActionBarSkin()
	{
		super();
 
		borderClass = null;
	}
 
	override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
	{
		var fillColors:Array = (getStyle("actionBarColors") == null) ? mFillColors : getStyle("actionBarColors");
		var fillAlphas:Array = (getStyle("actionBarAlphas") == null) ? mFillAlphas : getStyle("actionBarAlphas");
		var fillRatios:Array = (getStyle("actionBarRatios") == null) ? mFillRatios : getStyle("actionBarRatios");
 
		var lineColor:uint = (isNaN(getStyle("lineColor"))) ? mLineColor : getStyle("lineColor");
		var lineWeight:int = (isNaN(getStyle("lineWeight"))) ? mLineWeight : getStyle("lineWeight");
 
		colorMatrix.createGradientBox(unscaledWidth, unscaledHeight, Math.PI / 2, 0, 0);
 
		graphics.beginGradientFill(GradientType.LINEAR, fillColors, fillAlphas, fillRatios, colorMatrix);
		graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
		graphics.endFill();
 
		graphics.beginFill(lineColor, 1);
		graphics.drawRect(0, unscaledHeight - lineWeight, unscaledWidth, lineWeight);
		graphics.endFill();
	}
}
}

Whats going on in that code?

  • Create a new MyActionBarSkin based off of the ActionBarSkin
  • Create a constructor that nulls out the border shadow (FXG)
  • Override the drawBackground() method to disabled ActionBarSkin from painting it’s background gradient based of chromeColor
  • Make up some new styles for our implementation so we can change things from the outside with CSS
    • actionBarColors, actionBarAlphas, actionBarRatios, lineColor, lineWeight
  • Create a Matrix box for gradient painting
  • Use Graphics.beginGradientFill() to paint the custom background gradient
  • Use Graphics.drawRect() to paint the bottom border line

Implementing the new skin

CSS code

s|ActionBar s|Button {
	color:#333333;
	textShadowAlpha:0;
}
 
s|ActionBar #titleDisplay {
	color:#333333;
	textShadowAlpha:0;
}
 
s|ActionBar {
	skinClass:ClassReference("skins.MyActionBarSkin");
	chromeColor:#BEBEBE;
	paddingTop:0;
	paddingBottom:0;
	/* add the new styles to override the base styles set in the skin*/
}

The message in the example is, with a little code, you can create vast amounts of reusable skins that are styled with your own custom CSS. Adobe purposly made skins basically styleless because there are somany different use cases out there. They leave it up to the developer to choose between FXG, Bitmaps or the programmatic approach with draws fast and is reusable.

Notes:

  • Setting defaults in the code is a good way to make your skin work out of the box.
  • getStyle() is NOT an expensive method call, setStyle() is expensive.
  • Making the default mutable style properties in the skin subclass protected allows the the developer to choose between actionscript and CSS. Properties can be updated in a subclass by setting them in the constructor without having to reimplement the drawing logic of the superclass.
  • The above class is simple and is not applying DPI resolution adjustments.
    • Note that this could be done using media quires in CSS adjusting the lineWeight style

What Are The ActionBar States

The ActionBar state;

  • titletitle with no actionContent or navigationContent
  • titleWithAction -titlewith actionContent and no navigationContent
  • titleWithNavigation -titlewith navigationContent and no actionContent
  • titleWithActionAndNavigation -titlewith navigationContent and actionContent
  • titleContenttitleContent with no title, actionContent or navigationContent
  • titleContentWithActiontitleContent with actionContent and no title or navigationContent
  • titleContentWithNavigationtitleContent with navigationContentand no title or actionContent
  • titleContentWithActionAndNavigation - titleContent with actionContent and navigationContent and no title

Conclusion

The ActionBar is a very usefull component based on established user interface design patterns. The key to using the ActionBar is understanding how it fits into the ViewNavigatorApplication and View. The ActionBar can also be used as a stand alone component in a regualr spark Application. Using the component in this manner requires the developer to wire everything up. The former, Adobe has already done some heavy lifting for the developer.

I will be writting more in depth about the ActionBar when the series progresses to ViewNavigators.

About the Author

Michael Schmalle has been developing Adobe Flex and the Flash Player since Flash version 5 (2002). He has numerous open source projects in ActionScript3 (including an ActionScript3 parser/lexer DOM for reading and writing AS3 source code) and Flex (user interface components). He has also been an active participant in the Flex community (just goolge him or Teoti Graphix, LLC) since 2004. He also realizes technologies change and is actively developing user interface components and applications on the Google Android mobile platform.

See Teoti Graphix. LLC.

GIT: https://github.com/teotigraphix

Twitter: http://twitter.com/TeotiGraphix/

Categories: AIR Mobile Tags: ,

AIR Mobile :: Hello Flex 4.6 – MobileUIToolkit1

December 1st, 2011 Michael Schmalle 4 comments

Hi,

Well things in the last month have been pretty fun, from the depths of the abyss back to a release of the Flex SDK that Adobe wants you to believe in. Hello Flex SDK and Flash Builder 4.6.

I’m not going to go into my opinion of what has gone on with the Flash is Dead popcorn that has been floating around the internet because it really doesn’t matter to me. What do I mean; Well having been with the Flash Player since it’s itty bitty version 5 (2002), I can’t abandon ship yet. There are those that stay and can repair the damage done by the drunk captain (In this case Adobe).

I really don’t think AIR for mobile is going away in the near future and that is what I have put my time into. I’m no stranger to Java and Android, which I love. I have re-consolidated my eggs based on the damage done by Adobe but I am still here ready to help those that see the true power in AIR for mobile cross platform applications.

Teoti Graphix, LLC is here to offer a new mobile component toolkit. I’m ironing out the creases and finishing up the documentation but, next week I will release our first mobile toolkit MobileUIToolkit1.

The Components

  • PopUp – A self contained class that acts much like Android’s Toast with duration layout placement and more.
  • Dialog – The base for all dialogs used with the PopUp.
  • AlertDialog – A modal or non modal dialog that uses events and implements a button provider for it’s control buttons.
  • TextDialog – A dialog that uses a custom text content renderer (this is the default PopUp dialog).
  • ProgressBar – A progress bar that implements primary, secondary and indeterminate values with optional direction switching. As well as many styles to adjust the look through CSS.
  • MobileButton – A simple implementation of a spark Button that includes a longClick event and longClickDelay style.
  • Picker – A simple increment – decrement picker with dataProvider and data cycling.
  • RatingBar – The cliche mobile component that everybody needs. The component is based off of the ProgressBar which gives it even more power and usability. The RatingBar is touch-drag enabled.
  • WebView – A simple UIComponent implementation of the StageWebView. Note this is an "extra" and may not work in some mobile application designs due to the native nature of the StageWebView.

The component kit offers time saving unit tested code with over 8 years of Flash Player component development. All of our components are tested and documented at the professional level a mobile application developer can feel confident in using.

Check out the documentation of the PopUp class;

PopUp class Reference

All of our component kits come with support response time within 24 hours excluding weekends and holidays. You can google our company and see we have been on the front lines helping the Flex/AIR community since Flex version 2.

All of our mobile component skins are optimized in ActionScript and some have secondary MXML skins for those that want them. Skins are also DPI aware and will adjust according to the Application’s DPI.

The above being said, I had the pleasure of participating in the 4.6 pre-release program and have put together a large Hello World style blog article series for all of the Flex 4.6 mobile components. Stay tuned, I will start posting these next week.

Why buy from Teoti Graphix, LLC: We have been doing this longer than anybody creating custom flash/flex components and we are not going anywhere, just look us up. Unit tests? Who needs them, you do and have the ability to purchase them as well with all the source code.

Again; If you want to see pretty images and professional documentation visit;

PopUp class Reference

Some images of our new toolkit; (Every component can be skinned and styled)

AlertDialog

Picker

Text PopUp

Icon Text PopUp

ProgressBar

ProgressBar

RatingBar

More to come;

Mike