Archive for May, 2008

I made some experiments on how to easily access to data in a Flash site. It is probably a mix with good and bad ways but I think it is worth having a look.

What I’ve done here is get data with syntax that is similar to what you get using E4X in AS3. For example with XML and E4X you can use syntax like that:

xml..item[2].author.name.text();

I’m not saying that this experiment is a good practice but I want to show you what you can do by extending the Array class and extending the Proxy class in AS3. The Proxy class is the replacement of the __resolve we were using in AS2.

Let’s say we have a website that will load data from a database at the start, for example using AMFPHP or whatever, and we are going to fill this data at run-time.

In my example I have a kind of tree with countries > cities > people.

I would like to be able to loop easily through the data, as well as getting them with a friendly/readable syntax if needed.

In my example, I have a Singleton class that contains all the data. I don’t load the data in my example, I statically fill the class. I will access to the data like that:

Content.data

This will return me a array of data, which will contains an array of countries, each instance of the country array will contains an array of cities, which will contains an array of people, etc…

So I’d like to access to my data like this:

To browse the countries:
Content.data[0]
Content.data[1]

To browse the cities in the countries:
Content.data[0][0]
Content.data[0][1]

To browse the people in the cities:
Content.data[0][0][0]
Content.data[0][0][1]

That’s nice to loop through with a “for each” or whatever. An Array is a pretty nice tool to store data as you get some functions to manage it like push, splice, reverse, etc.

But these arrays have a problem, what if I need to get more info on my countries, like the weather, an ID or the surface of the country? I would like access to more data like that:

Content.data[0].name
Content.data[0].id

This is possible with an Array as it is one of the few classes in AS3 that are dynamic. It means you can set any property at run time. For example MovieClip is dynamic and Sprite is not, try to add properties at run-time on these classes to see the result. Some people are saying that is it a good and bad things. It is easy to use but you don’t know what kind of properties will be added in your Array at run-time.

So you don’t want that, and better, you want to control what kind of data they are going to put in your Array. We will get that by extending the Array class.

There’s a nice explanation here to extends an Array, as well as control the data type your custom Array class will accept.

So far it is not bad, we can easily access to our data, we can have properties on these arrays and finally we know that we will have the right type of content inside.

The other thing I want is access to my data with a nice E4X-like:

Content.data.France.name
Content.data.France.Paris.name

Easy, we just need a property France on this array and it is done. Well, the thing is we don’t know yet what this array will be filled with, so we are talking about dynamic properties. These dynamic properties will have to be added to the array when we create it because we said we want to control and we don’t want people adding their own properties.

How do we do that?

We’re going to use the Proxy class that make able us able to handle dynamic properties and dynamic calling.

We will have a class that will be an array (what you get when you call Content.data), a class for the countries, a class for the cities and a class for the people. The people class won’t be an array.

So we have the classes DataArray, CountryArray and CityArray that are extending the Array class. We will also have a Proxy class (a class that is extending the Proxy one) for each of the Array. I choose to a Proxy class for each Array class as it is easier to understand.

Let’s see a bit of code.

The Singleton Content class

Actionscript:
  1. package com.soundstep.data {
  2.  
  3.     /**
  4.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  5.      * <b>Class version:</b> 1.0<br />
  6.      * <b>Actionscript version:</b> 3.0<br />
  7.      * <b>Copyright:</b> Free to use and change (except to include in a framework), an notification email will be welcome for a commercial use (just for information).<br />
  8.      * <b>Date:</b> 05-2008<br />
  9.      * <b>Usage:</b> Manage a Section
  10.      * @example
  11.      * <listing version="3.0">
  12.        
  13.      * </listing>
  14.      */
  15.    
  16.     public class Content {
  17.        
  18.         //------------------------------------
  19.         // private properties
  20.         //------------------------------------
  21.        
  22.         private static var content:Content = new Content();
  23.         private static var _data:Data;
  24.        
  25.         //------------------------------------
  26.         // public properties
  27.         //------------------------------------
  28.        
  29.        
  30.        
  31.         //------------------------------------
  32.         // constructor
  33.         //------------------------------------
  34.        
  35.         public function Content() {
  36.             if (content) throw new Error("Content is Singleton and can only be accessed through Content.data");
  37.             if (_data == null) buildData();
  38.         }
  39.        
  40.         //
  41.         // PRIVATE, INTERNAL
  42.         //________________________________________________________________________________________________
  43.        
  44.         private function buildData():void {
  45.             _data = new Data();
  46.            
  47.         }
  48.        
  49.         //
  50.         // PUBLIC
  51.         //________________________________________________________________________________________________
  52.        
  53.         public static function get data():Data {
  54.             return _data;
  55.         }
  56.        
  57.     }
  58.    
  59. }

The Data and DataArray class

The DataArray is extending the Array class. To be able to extend the Array class you need the dynamic keyword before the class.

dynamic public class DataArray extends Array {

We have a private property type Class used to control the Data we will push in our extended Array.

private var dataType:Class;

To control the type pushed we have to overwrite 4 functions: push, concat, splice and unshift, as it is nicely explained in the AS3 documentation.

Here is the code:

Actionscript:
  1. package com.soundstep.data {
  2.  
  3.     /**
  4.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  5.      * <b>Class version:</b> 1.0<br />
  6.      * <b>Actionscript version:</b> 3.0<br />
  7.      * <b>Copyright:</b> Free to use and change (except to include in a framework), an notification email will be welcome for a commercial use (just for information).<br />
  8.      * <b>Date:</b> 05-2008<br />
  9.      * <b>Usage:</b> Manage a Section
  10.      * @example
  11.      * <listing version="3.0">
  12.        
  13.      * </listing>
  14.      */
  15.    
  16.     dynamic public class DataArray extends Array {
  17.        
  18.         //------------------------------------
  19.         // private properties
  20.         //------------------------------------
  21.        
  22.         private var dataType:Class;
  23.  
  24.         //------------------------------------
  25.         // public properties
  26.         //------------------------------------
  27.                
  28.         //------------------------------------
  29.         // constructor
  30.         //------------------------------------
  31.        
  32.         public function DataArray(...args) {
  33.             dataType = Country;
  34.             for (var i:int=0; i<args.length; i++) this.push(args[i]);
  35.             length = length;
  36.         }
  37.        
  38.         //
  39.         // PRIVATE, INTERNAL
  40.         //________________________________________________________________________________________________
  41.        
  42.         //
  43.         // PUBLIC
  44.         //________________________________________________________________________________________________
  45.        
  46.         AS3 override function push(...args):uint {
  47.             for (var i:* in args) {
  48.                 if (!(args[i] is dataType)) {
  49.                     trace("Error: you must push an Object type Country");
  50.                     args.splice(i,1);
  51.                 }
  52.             }
  53.             return super.push.apply(this, args);
  54.         }
  55.         
  56.         AS3 override function concat(...args):Array {
  57.             var passArgs:DataArray = new DataArray();
  58.             for (var i:* in args) passArgs.push(args[i]);
  59.             return super.concat.apply(this, passArgs);
  60.         }
  61.        
  62.         AS3 override function splice(...args):* {
  63.             if (args.length> 2) {
  64.                 for (var i:int=2; i<args.length; i++) {
  65.                     if (!(args[i] is dataType)) args.splice(i,1);
  66.                 }
  67.             }
  68.             return super.splice.apply(this, args);
  69.         }
  70.         
  71.         AS3 override function unshift(...args):uint {
  72.             for (var i:* in args) {
  73.                 if (!(args[i] is dataType)) args.splice(i,1);
  74.             }
  75.             return super.unshift.apply(this, args);
  76.         }
  77.        
  78.     }
  79.    
  80. }

To create a new DataArray instance, we actually don’t use the DataArray class directly but his Proxy, that will handle the dynamic properties.

I named the class Data, it is what you get with Content.data.

To extend the Proxy class you need to import the class itself and its namespace:

import flash.utils.Proxy;
import flash.utils.flash_proxy;

Proxy is also a dynamic class:

dynamic public class Data extends Proxy {

We have our private var that will be our DataArray instance:

private var _item:DataArray;

To control the properties and method called through our Proxy, we need to override 3 methods (with the namespace flash_proxy):

override flash_proxy function callProperty(methodName:*, ... args):* {
override flash_proxy function getProperty(name:*):* {
override flash_proxy function setProperty(name:*, value:*):void {

When you will call an unknown method, the Proxy class invoke callProperty, and when you will call or set a property (like Content.data.France), the Proxy class invoke getProperty and setProperty.

In my example I trace an Error if you try to set your own property, this is our control. When you get a property, I loop through the DataArray instance to see if I’ve got an item with that name. We could do it with the id or any property of your choice (that is in the DataArray class), and if yes I return it. This is the instance you get by using Content.data.France.

So in brief, when I call Content.data.France, I’m going through the Proxy that is basically managing the dynamic properties added at run-time. The DataArray class is extending the Array class to control the properties and data type.

Here is the code of the Data class:

Actionscript:
  1. package com.soundstep.data {
  2.  
  3.     /**
  4.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  5.      * <b>Class version:</b> 1.0<br />
  6.      * <b>Actionscript version:</b> 3.0<br />
  7.      * <b>Copyright:</b> Free to use and change (except to include in a framework), an notification email will be welcome for a commercial use (just for information).<br />
  8.      * <b>Date:</b> 05-2008<br />
  9.      * <b>Usage:</b> Manage a Section
  10.      * @example
  11.      * <listing version="3.0">
  12.        
  13.      * </listing>
  14.      */
  15.  
  16.     import flash.utils.Proxy;
  17.     import flash.utils.flash_proxy;
  18.    
  19.     dynamic public class Data extends Proxy {
  20.        
  21.         //------------------------------------
  22.         // private properties
  23.         //------------------------------------
  24.        
  25.         private var _item:DataArray;
  26.        
  27.         //------------------------------------
  28.         // public properties
  29.         //------------------------------------
  30.                
  31.         //------------------------------------
  32.         // constructor
  33.         //------------------------------------
  34.        
  35.         public function Data(...args) {
  36.             _item = new DataArray();
  37.             for (var i:int=0; i<args.length; i++) _item.push(args[i]);
  38.         }
  39.        
  40.         //
  41.         // PRIVATE, INTERNAL
  42.         //________________________________________________________________________________________________
  43.        
  44.         private function getString():String {
  45.             var s:String = "";
  46.             for (var i:uint=0; i<_item.length; i++) {
  47.                 s += "index:" + i + ", id:" + _item[i].id + ", name:" + _item[i].name;
  48.                 if (i <_item.length-1) s += "\n";
  49.             }
  50.             if (_item.length == 0) return _item.name + " is empty";
  51.             else return s;
  52.         }
  53.        
  54.         //
  55.         // PUBLIC
  56.         //________________________________________________________________________________________________
  57.        
  58.         override flash_proxy function callProperty(methodName:*, ... args):* {
  59.             var res:*;
  60.             switch (methodName.toString()) {
  61.                 case 'clear':
  62.                     _item = new DataArray();
  63.                     break;
  64.                 case 'list':
  65.                     trace(getString());
  66.                     break;
  67.                 default:
  68.                     res = _item[methodName].apply(_item, args);
  69.                     break;
  70.             }
  71.             return res;
  72.         }
  73.  
  74.         override flash_proxy function getProperty(name:*):* {
  75.             for each (var i:* in _item) {
  76.                 if (name == i.name) {
  77.                     return i;
  78.                     break;
  79.                 }
  80.             }
  81.             return _item[name];
  82.             throw new Error("ERROR: Property " + name + " not found!");
  83.         }
  84.  
  85.         override flash_proxy function setProperty(name:*, value:*):void {
  86.             trace("ERROR: You can't set your own property!");
  87.         }
  88.        
  89.         public function toString():String {
  90.             return getString();
  91.         }
  92.     }
  93. }

Basically the cities and countries classes are doing the same, the dataType and properties are different, a country is asking a City type and the a city is asking a People type.

For example the CountryArray class asks an id and name to create the array, you have to use a syntax like:

var france:Country = new Country(0, "France");

As it is an Array extended you can still pass more arguments (but they have to be the right type), the type here is City, that is also an Array extended but a city instance is asking an id, a name and weather as parameters:

var france:Country = new Country(0, "France", new City(0, "Paris", "As bad as London!"), new City(1, "Marseille", "More sun than Paris"));

Here is how I fill the Content with some examples:

Actionscript:
  1. //country
  2. var france:Country = new Country(0, "France");
  3. Content.data.push(france);
  4. var uk:Country = new Country(1, "UK");
  5. Content.data.push(uk);
  6.  
  7. // city
  8. var paris:City = new City(0, "Paris", "As bad as London!");
  9. france.push(paris);
  10. france.myvar = "qwe";
  11. var marseille:City = new City(1, "Marseille", "More sun than Paris");
  12. france.push(marseille);
  13. var london:City = new City(0, "London", "Quite bad!");
  14. uk.push(london);
  15. var liverpool:City = new City(1, "Liverpool", "Even worst than London");
  16. uk.push(liverpool);
  17.  
  18. // people
  19. var franck:People = new People(0, "Franck", "Dupont", 29);
  20. paris.push(franck);
  21. var stephane:People = new People(1, "Stephane", "Durand", 42);
  22. paris.push(stephane);
  23. var john:People = new People(0, "John", "Doe", 35);
  24. london.push(john);
  25. var david:People = new People(0, "David", "Doe", 37);
  26. london.push(david);

And finally here is some example to access to your data:

Actionscript:
  1. Content.data.length
  2. Content.data.France.length
  3. Content.data[0].name
  4. Content.data.France.name
  5. Content.data.France[0].name
  6. Content.data.France.Paris.name
  7. Content.data.France.Paris.Franck.name
  8. Content.data[0][0][0].name

I didn’t optimize/clean the classes and as I said, I’m not saying that it is a good way of accessing data in Flash, but it shows you how to control data type, how to extend an Array, how to extend the Proxy class and how to handle properties and methods of a class at low-level.

Download the source.

Vote in HexoSearch

Comments No Comments »

A quick post for an AS2 class I wrote. I won't do that a lot as I'm not really using AS2 anymore.

Have you ever had a Button in another Button in as2? Or let's say, you wanted a onRollOver on a MovieClip and a onRelease on another MovieClip in this MovieClip?

Well, it happened to me several times and this is just not possible by using only onRelease and onRollOver in the same time. In AS2, the first onRelease or whatever you use that will give a pointer cursor will "block" the onRelease/onRollOver of the children, annoying...

In AS3, life is easy, you manage it with the mouseChildren and buttonMode properties.

I don't know how you solved this problem, maybe there's another simpler solution (let me know, I'm curious) but mine was to play with the hitTest method of the MovieClip.

I wrote a class that I found useful for me. After creating a instance with the MovieClip target as a parameter, the class dispatch a MouseManager.MOUSE_OVER and MouseManager.MOUSE_OUT.

You can see a demo and download the source.

The code of the class:

Actionscript:
  1. /*
  2. *
  3. * Copyright info: Free to use and change, an notification email will be welcome for a commercial use
  4. * Actionscript: built for actionscript 2.0
  5. * 05-2008
  6. *
  7. * @author      Romuald Quantin - romu@soundstep.com - www.soundstep.com
  8. * @version    1.0
  9. * @usage
  10. *
  11. */
  12.  
  13.  
  14. import mx.utils.Delegate;
  15. import mx.events.EventDispatcher;
  16.  
  17. class com.soundstep.utils.managers.MouseManager {
  18.    
  19.     private var __target:MovieClip;
  20.     private var __mouseListener:Object;
  21.     private var __over:Boolean = false;
  22.     private var dispatchEvent:Function;
  23.    
  24.     public var addEventListener:Function;
  25.     public var removeEventListener:Function;
  26.    
  27.     public static var MOUSE_OVER:String = "mouse_over";
  28.     public static var MOUSE_OUT:String = "mouse_out";
  29.    
  30.     public function MouseManager(target:MovieClip) {
  31.         EventDispatcher.initialize(this);
  32.         __target = target;
  33.         __mouseListener = {};
  34.         Mouse.addListener(__mouseListener);
  35.         __mouseListener.onMouseMove = Delegate.create(this, mouseOverOut);
  36.         mouseOverOut();
  37.     }
  38.    
  39.     // PRIVATE
  40.     //__________________________________________________________
  41.    
  42.     private function mouseOverOut():Void {
  43.         var xMousePos:Number = _level0._xmouse;
  44.         var yMousePos:Number = _level0._ymouse;
  45.         if (__target.hitTest(xMousePos, yMousePos, true)) {
  46.             if (!__over) {
  47.                 __over = true;
  48.                 this.dispatchEvent({type:MouseManager.MOUSE_OVER, target:__target});
  49.             }
  50.         }
  51.         else {
  52.             if (__over) {
  53.                 __over = false;
  54.                 this.dispatchEvent({type:MouseManager.MOUSE_OUT, target:__target});
  55.             }
  56.         }
  57.     }
  58.    
  59.     // PUBLIC
  60.     //__________________________________________________________
  61.    
  62.     public function get over():Boolean {
  63.         return __over;
  64.     }
  65.    
  66. }

and how to use it:

Actionscript:
  1. import mx.utils.Delegate;
  2. import com.soundstep.utils.managers.MouseManager;
  3.  
  4. var mm:MouseManager = new MouseManager(mc);
  5. mm.addEventListener(MouseManager.MOUSE_OVER, Delegate.create(this, mouseOver));
  6. mm.addEventListener(MouseManager.MOUSE_OUT, Delegate.create(this, mouseOut));
  7.  
  8. var t:String = mc.mcText.text;
  9.  
  10. function mouseOver():Void {
  11.     mc.mcText.text = t + " rollover";
  12. }
  13.  
  14. function mouseOut():Void {
  15.     mc.mcText.text = t;
  16. }
  17.  
  18. mc.bt.onRollOver = function():Void {
  19.     this.btText.text = "Button in MovieClip rollover";
  20. }
  21.  
  22. mc.bt.onRollOut = function():Void {
  23.     this.btText.text = "Button in MovieClip";
  24. }

Vote in HexoSearch

Comments 4 Comments »

I made some updates in BaseUI. You don't have to change a code already written, it is just bugs correction or functionalities added.

The demo, docs and source in the download page are updated.

Version 1.0.8 - The elements are now correctly refreshed when created if they are not visible (alpha or visible properties)

Version 1.0.7 - The elements are now correctly refreshed when a position or a margin is changed

Version 1.0.6 - Bug correction with the margin when using a type background mode ratio out

Version 1.0.5 - refresh method added in BaseUI

you can refresh all the elements of a BaseUI instance:

Actionscript:
  1. baseUI.refresh();

Version 1.0.4 - The Element is added to the list-to-render if the DisplayObject is already in the display list

When you create a ElementUI by adding a DisplayObject to a BaseUI instance, if this DisplayObject has been already added to the display list, the ElementUI is now added it correctly to the render list. This wasn't possible before:

Actionscript:
  1. var s:Sprite = new Sprite();
  2. addChild(s);
  3. var e:ElementUI = baseUI.addElement(s);

Version 1.0.3 - Refresh method in ElementUI is now public

It makes you able to access to the refresh method:

Actionscript:
  1. var e:ElementUI = baseUI.getElement(mySprite);
  2. e.refresh();

Version 1.0.2 - removeAllElements method added in BaseUI

You can remove All the elements in BaseUI:

Actionscript:
  1. baseUI.removeAllElements();

Version 1.0.1 - Alignment and position for the background in mode ratio out is now respected

It makes you able to set the alignment of a ElementUI type background in mode ratio out. This wasn't possible before and was always aligned top left.

Vote in HexoSearch

Comments 2 Comments »

Click here to access to BaseUI page with demo, documentation and source.

This is a tutorial to explain you what you can do with BaseUI. It will not build a website for you (not yet :) ) but should reduce your efforts by handling basic and common rules in a flash site, such as position, margin and resize of a DisplayObject.

I didn't test all the DisplayObject subclasses, so you might find funny results if a subclass is not working as expected. BaseUI is a young class I'm using for my own project and obviously needs debugging, more testing and improvement.

Here is a list (Non-Exhaustive) of some DisplayObject subclasses you can use with BaseUI.

Bitmap, DisplayObjectContainer, Loader, Sprite, FLVPlayback, MovieClip, UIComponent, Label, NumericStepper, ProgressBar, ScrollBar, Slider, TextArea, TextInput, UILoader, SimpleButton, TextField, MorphShape, Shape, StaticText, Video.

Let's get started.

Creating a BaseUI instance

BaseUI extends EventDispatcher and is basically managing a list of DisplayObject and a list of DisplayObject to render (I mean render by changing the position and the size).

BaseUI is not a Singleton, you can create as many instance as you wish.

Usually, I'm creating a main BaseUI instance in the main class, the entry point, to manage most of my elements. As you can see in the demo, the central window is a Sprite with its own BaseUI instance.

Example in the main class (which is extending Sprite or MovieClip):

Actionscript:
  1. import com.soundstep.ui.*
  2. var baseUI:BaseUI = new BaseUI(this);

Adding Elements as ElementUI

Now that we have our instance, we can start to add a DisplayObject in the list. BaseUI has 3 public methods: addElement, removeElement and getElement.

You can get an array of the elements added with the elements property of the BaseUI instance:

Actionscript:
  1. var allElements:Array = baseUI.elements;

The addElement will return an instance of the ElementUI class. This instance has the properties needed to handle the behavior of the DisplayObject.

Actionscript:
  1. var element:ElementUI = baseUI.addElement(mySprite);

This action add the DisplayObject to the BaseUI list and when you will add the sprite to the display list by using addChild(mySprite), the DisplayObject will be automatically added to the list-to-render in the BaseUI class, and then apply the rules set in the ElementUI instance.

You can get the ElementUI created like this:

Actionscript:
  1. var element:ElementUI = baseUI.getElement(mySprite);

You can remove an element from the list like this:

Actionscript:
  1. baseUI.removeElement(mySprite);

Note: If you remove the DisplayObject from the display list using removeChild(mySprite), the BaseUI removes the element from the list-to-render but the element is still listed in the BaseUI instance until you use the removeElement method. It means you can remove a child from the display list and add it again, the BaseUI will still apply the rules you have set to this element.

Type of an ElementUI

An ElementUI instance can be two types: element that is the default one and background. Some rules are common and some others are only working with a certain type. The class will throw an error if you try to do something wrong.

You can set the type when you add the element to the BaseUI instance or later.

Add a DisplayObject type element:

Actionscript:
  1. var element:ElementUI = baseUI.addElement(mySprite);

or

Actionscript:
  1. var element:ElementUI = baseUI.addElement(mySprite, ElementUI.TYPE_ELEMENT);

Add a DisplayObject type background:

Actionscript:
  1. var element:ElementUI = baseUI.addElement(mySprite, ElementUI.TYPE_BACKGROUND);

Change the type of an element:

Actionscript:
  1. element.type = ElementUI.TYPE_ELEMENT;
  2. element.type = ElementUI.TYPE_BACKGROUND;

Reference to the ElementUI

Before we start to change the size and position of an element, you have to understand on which DisplayObject you align or resize to.

An ElementUI instance has a property onStage, the default is true. It means if you add a 10 pixels margin top, it will be 10 pixels from the top of the stage.

When I build a site, I'm using an element (like a logo, a menu, a page, a footer or whatever) like I would do in Photoshop, on a layer that is taking the whole area. That's why the onstage is set to true by default, you can change it like this:

Actionscript:
  1. element.onStage = false;

By doing this, you tell the Element to react, not with the stage anymore but with the parent DisplayObject. We will call it the DisplayObject reference, so the stage or the parent.

In the demo, the property onStage of the ElementUI in the Window are set to false because I want them to react with the window Sprite (DisplayObject reference), not the stage.

You have to be careful using an onStage property set to false, because it means the DisplayObject reference need to have a size to behave as expected.

For example, in a site, your main area is an invisible rectangle 800x600 (a container) that is always centered in the DisplayObject reference (the stage in my example). You can set the ElementUI onStage property of the DisplayObject in the container to false to make the elements behave as expected. It means the invisible container will have to have a width and height. The central window in the demo is working like that, Here is a hack to do that:

Actionscript:
  1. var container:Sprite = new Sprite();
  2. container.graphics.beginFil(0xFF0000, 0);
  3. container.graphics.drawRect(0, 0, 800, 600);
  4. addChild(container);

I draw an invisible rectangle (the alpha is set to 0) in my container to be sure the DisplayObject reference (the container) of my ElementUI has a size, and then make the ElementUI inside behave as expected.

Note: at the moment the type background is not working with a property onstage set to false, probably a further development.

Alignment

The alignment is a common property for both types, you can align an ElementUI to top, bottom, left, right and center. You have to set your alignment to an axis. The following example aligns an ElementUI to the right and the bottom of the DisplayObject reference:

Actionscript:
  1. element.alignX = ElementUI.ALIGN_RIGHT;
  2. element.alignY = ElementUI.ALIGN_BOTTOM;

Here is the list of the alignment

Actionscript:
  1. element.alignX = ElementUI.ALIGN_LEFT;
  2. element.alignX = ElementUI.ALIGN_CENTER;
  3. element.alignX = ElementUI.ALIGN_RIGHT;
  4. element.alignY = ElementUI.ALIGN_TOP;
  5. element.alignY = ElementUI.ALIGN_CENTER;
  6. element.alignY = ElementUI.ALIGN_BOTTOM;

From the version 1.1.0 you can set the horizontal and vertical alignment when the element is centered.

Actionscript:
  1. element.horizontalAlign = 100;
  2. element.verticalAlign = -80;

Margin

The margin is also a common property for both types. Here is an example how to set a 10 pixels margin around a DisplayObject:

Actionscript:
  1. element.margin = 10;

You can set the margin only on a side, here is a list of the properties:

Actionscript:
  1. element.marginLeft = 10;
  2. element.marginRight = 10;
  3. element.marginTop = 10;
  4. element.marginBottom = 10;

The margin property can also accept an Object:

Actionscript:
  1. element.margin = {left:10, right:20, top:10, bottom:20};

Type background

This type can be used for a background or a slideshow for example. It has a specific property mode that is resizing a DisplayObject to fit the DisplayObject reference. When a picture or a video is resized, I strongly recommend using the smoothing property like this:

Actionscript:
  1. var bg:Bitmap = new Bitmap(new MyBitmap(0,0), PixelSnapping.AUTO, true);
  2. var element:ElementUI = baseUI.addElement(bg, ElementUI.TYPE_BACKGROUND);
  3. element.mode = ElementUI.RATIO_OUT;
  4. addChild(bg);

The three mode of the type background are ratio in, ratio out and ratio fit. Test the demo and see the behaviour of the different mode. You can use the alignment and margin with the mode.

The mode ratio fit is fitting the DisplayObject reference with the DisplayObject without keeping the ratio.

The mode ratio in is fitting the DisplayObject reference with the DisplayObject, keeping the ratio and you will always see the whole DisplayObject.

The mode ratio out is fitting the DisplayObject reference with the DisplayObject, keeping the ratio and you will always miss a part of the DisplayObject depending of the alignment.

Here is the syntax to set the mode:

Actionscript:
  1. element.mode = ElementUI.RATIO_FIT;
  2. element.mode = ElementUI.RATIO_IN;
  3. element.mode = ElementUI.RATIO_OUT;

Type Element

The type element has a property resizeOption. You can choose to resize the DisplayObject to fit the area in the width or the height. You can still use the margin and the alignment. It is useful for example to draw a line. Here is the syntax:

Actionscript:
  1. element.resizeOption = ElementUI.OPTION_ELEMENT_WIDTH;
  2. element.resizeOption = ElementUI.OPTION_ELEMENT_HEIGHT;

Example:

Actionscript:
  1. var lineAboveFooter:Sprite = new Sprite();
  2. lineAboveFooter.graphics.beginFill(0xFF0000);
  3. lineAboveFooter.graphics.drawRect(0, 0, 10, 1);
  4. var element:ElementUI = baseUI.addElement(lineAboveFooter);
  5. element.alignY = ElementUI.ALIGN_BOTTOM;
  6. element.margin = {left:20, right:20, bottom:30};
  7. element.resizeOption = ElementUI.OPTION_ELEMENT_WIDTH;
  8. addChild(lineAboveFooter);

This example will resize your Sprite to fit the DisplayObject reference, align it at 30 pixels from the bottom with a margin left and right of 20 pixels.

Note: For this example, use the drawRect with height 1 pixel as the drawLine method wasn't behaving as expected.

Initial Size

When a DisplayObject is added in the BaseUI instance, an ElementUI is created and at this moment, the Element instance is recording the size of the DisplayObject. This is the initialWidth and initialHeight of the DisplayObject. They are private property but it might change to public in further development.

This size is used to calculate the ratio of the mode for example.

An ElementUI instance has a property useInitialSize set by default to false, you can change it to true when you want the behaviour of the ElementUI working with the initial size. It is useful for example when you have a mask in a Sprite that is disturbing the width and height of this Sprite.

If you have an unexpected behaviour, if you find bugs or if you have ideas to improve BaseUI, just contact me.

I hope it helps.

Vote in HexoSearch

Comments 4 Comments »

I put in the downloads page the first version of BaseUI, classes I'm using all time, mostly to handle liquid UI site and portfolio/slideshow. You can also use it to get a centered fixed area on a background fitting the browser.

I'll post a tutorial and some tips when I'll get a chance, and probably later, a version to manage a liquid portfolio based on it.

Let me know what you think and if you have ideas to improve it.

Vote in HexoSearch

Comments 1 Comment »