From inspiration to realization
14Jul/101

set button width to text width in flex

Well, I have been working on a very interesting project recently, really stretching flex to the limits :-)
I needed to set buttons, linkButtons, Labels and more component's width to the width of the text inside them.
Usually, flex does it for you but the width was hardcoded in compile time and I needed to change the text and the width in runtime and resize the component according to that.

I have written a nifty helper function for that.

here it is:

/**
* This function will accept the text and the UI component and set the width to the width of the text
* @param text the text or label of the component
* @param container the container casted to a UIComponent
*
*/
public static function measureTextWidthAndResizeComponent(text:String, container:UIComponent):void
{
	var _measuredWidth:Number = 0;
	var  _paddingLeft:uint = 0;
	var _paddingRight:uint = 0;
	var _horizontalGap:uint = 0;
	var _addedToWidth:int;

	if(text == null)
		return;

	if(text.length <= 1)
		return;

	_paddingLeft = container.getStyle("paddingLeft");
	_paddingRight = container.getStyle("paddingRight");
	_horizontalGap = container.getStyle("horizontalGap");

	_addedToWidth = int(_horizontalGap + _paddingLeft + _paddingRight);

	var lineMetrics:TextLineMetrics = container.measureText(text);

	_measuredWidth = (lineMetrics.width + _addedToWidth);
	container.width = _measuredWidth;
}

That's it, enjoy!

  • Share/Bookmark
22Jun/102

Copy object properties to another object – Flex

In a project I am working on with Flex and AS3 I needed to copy all of the object's properties and accessors to another object.
because I didn't want to hard code the properties for various reasons I needed to write a function that will "crawl" the object properties and accessors and copy then to the new object.

I created a static function that does exactly that

		/**
		 * copies a source object to a destination object
		 * @param sourceObject the source object
		 * @param destinationObject the destination object
		 *
		 */
		public static function copyObject(sourceObject:Object, destinationObject:Object):void
		{
			// check if the objects are not null
			if((sourceObject) && (destinationObject)) {
				try
				{
					//retrive information about the source object via XML
					var sourceInfo:XML = describeType(sourceObject);
					var objectProperty:XML;
					var propertyName:String;

					// loop through the properties
					for each(objectProperty in sourceInfo.variable)
					{
						propertyName = objectProperty.@name;
						if(sourceObject[objectProperty.@name] != null)
						{
							if(destinationObject.hasOwnProperty(objectProperty.@name)) {
								destinationObject[objectProperty.@name] = sourceObject[objectProperty.@name];
							}
						}
					}
					//loop through the accessors
					for each(objectProperty in sourceInfo.accessor) {
						if(objectProperty.@access == "readwrite") {
							propertyName = objectProperty.@name;
							if(sourceObject[objectProperty.@name] != null)
							{
								if(destinationObject.hasOwnProperty(objectProperty.@name)) {
									destinationObject[objectProperty.@name] = sourceObject[objectProperty.@name];
								}
							}
						}
					}
				}
				catch (err:*) {
					;
				}
			}

This function will copy everything, you can simply add an "allowedProperties" definition and make the function only copy definitions and properites which exist in your allowed definition.

like so:

private static var allowedProperties:String = "height,width,visible,styleName,x,y,alpha,visible,source,dataProvider,styleDecleration,text,label,horizontalScrollPolicy,labelField,";

		public static function copyDisplayObjectData(sourceObject:Object, destinationObject:Object):void
		{
			if((sourceObject) && (destinationObject)) {
				try
				{
					var sourceInfo:XML = describeType(sourceObject);
					var objectProperty:XML;
					var propertyName:String;
					
					for each(objectProperty in sourceInfo.variable)
					{
						propertyName = objectProperty.@name;
						if(allowedProperties.indexOf(propertyName) > -1)
						{
							if(sourceObject[objectProperty.@name] != null)
							{
								if(destinationObject.hasOwnProperty(objectProperty.@name)) {
									destinationObject[objectProperty.@name] = sourceObject[objectProperty.@name];
								}
							}

						}
					}
					
					for each(objectProperty in sourceInfo.accessor) {
						if(objectProperty.@access == "readwrite") {
							propertyName = objectProperty.@name;
							if(allowedProperties.indexOf(propertyName) > -1)
							{
								if(sourceObject[objectProperty.@name] != null)
								{
									if(destinationObject.hasOwnProperty(objectProperty.@name)) {
										destinationObject[objectProperty.@name] = sourceObject[objectProperty.@name];
									}
								}
							}
						}
					}
				}
				catch (err:*) {
					;
				}
			}
		}

That's it, tricky but absolutely can be done :-)

  • Share/Bookmark
10Jun/101

Empty dialogs in flex builder 3 + Flash builder 4

This week I needed to work with My PC on a flex project, I usually stay away of the PC with flex projects, I'm used to working on the mac with these project but I needed to work on the PC.

While trying to configure the project in flex builder 3 (and with 4 as well) I stumbled upon a weird bug that made me scratch my head for a while.
The bug was that all of the dialogs appeared empty, no configuration, almost no buttons.

Here's a screenshot of the problem:

Now, I remembered a teammate I had a while back had the same problem and it appeared to be a WACOM with a windows 7 driver that caused the problem so I started disabling devices one after the other.

The problem was a logitech mouse software I have installed on the pc, once I quited this application everything went back to normal.

Here's the icon on the taskbar. (not hard to trace)

Hope this post helps you and you won't scratch your had for hours like I did.

  • Share/Bookmark
30May/102

Access flex application through the SWFLoader component

Often you load flex applications through another flex application using the SWFLoader component.
it's not that common knowledge that you can actually access all of that application exactly the same way you are accessing your own application.

What does that mean?

It means you can access that application components, get the children and get a good knowledge on how this application is build, you can also access it's component and dispatch events.

OK, how?

Let's start doing it. we will create a simple application, put an SWFLoader on stage and create a listener for the complete event.
Lets's also add 2 global variables, one for SystemManager, another for IUIComponent (I will explain later)

This is what the application code should look like:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600">
	<mx:Script>
		<![CDATA[
			import mx.core.IUIComponent;
			import mx.managers.SystemManager;

			private var _systemManager:SystemManager;
			private var _innerApplication:IUIComponent;

			protected function loader_completeHandler(event:Event):void
			{
				_systemManager = SystemManager(loader.content);
			}
		]]>
	</mx:Script>

	<mx:SWFLoader id="loader" source="VistaRemix.swf" width="800" height="600" autoLoad="true" complete="loader_completeHandler(event)"/>
</mx:Application>

As you can probably see, we are assigning a value to _systemManager when the loader (SWFLoader) finished loading, this enables us to work with that application system Manager and access properties.

Continuing...

We will add 2 Event listeners inside that function

_systemManager.addEventListener(FlexEvent.APPLICATION_COMPLETE, sysManage_ApplicationComplete_Handler);
_systemManager.addEventListener(FlexEvent.UPDATE_COMPLETE, sysManage_UpdateComplete_Handler);

Now that we have those in place, let's add the closure functions

			private function sysManage_UpdateComplete_Handler(event:FlexEvent):void
			{
				_innerApplication = _systemManager.application;
			}

			private function sysManage_ApplicationComplete_Handler(event:FlexEvent):void
			{
				_innerApplication = _systemManager.application;
			}

Great, now _innerApplication is actually an application, you can get it's children, get properties, get components, dispatch events and more.

This comes in very handy when you want control over an application and you don't have the source, you can create a clone of that application and create your own GUI for it, it's an amazing feature.

This is a screenshot of debugging mode, check out the debugger watch section, these are all methods you can use on that variable, you can of course use much more...

Debug view of the application in Flash builder 4

Good luck!

  • Share/Bookmark
Tagged as: , , 2 Comments
24May/100

Flash builder 4 – sharing a project with your team using SVN Screencast

In this post I will show you how you can share a project with your team using SVN and flash buider 4.

This is my first screencast in English after quite a few in my native tongue language so please excuse me is I stutter or swallow some of my words, I promise to keep getting better with time.

  • Share/Bookmark