Home » ActionScript 3.0, Adobe, Flex 3

FLEX 3 - Chrome e RawChildren: aggiungere elementi visuali alle parti ‘protette’ di un componente

30 June 2009 No Comment

Tutti i componenti Flex sono essenzialmente formati da due sezioni: la classica area di layout, in cui e’ possibile inserire agevolmente elementi visuali tramite tag MXML o attraverso il classico metodo addChild(), e un’area definita Chrome rappresentata da tutti gli altri spazi, come barra del titolo, scrollbars, margini, footer e cosi via’ in cui solitamente e’ impossibile scrivervi.

Estenderemo quindi la classe Panel ridefinendo i suoi metodi createChildren() e updateDisplayList() (esponendo quindi il concetto di override di un metodo) e utilizzeremo la proprieta’ rawChildren per scrivere nella titleBar.

001_intro

Per inserire nuovi elementi all’interno di queste aree “protette” sara’ quindi necessario creare una nuova classe che estende il componente Panel e utilizzare la proprieta’ rawChildren per scrivere all’interno della Chrome Area.

In questo esercizio vedremo quindi come inserire un componente Button all’interno della TitleBar del Panel e assoceremo a tale pulsante la funzionalita’ di resize 100% affinche’ ad ogni suo click il pannello venga esteso al 100% in altezza e larghezza (vedi immagine seguente)

002_enlarge





ESTENDERE IL COMPONENTE PANEL

Innanzitutto creiamo un nuovo progetto Flex e inseriamo una nuova classe chiamata ExtendedPanel.as all’interno di una cartella denominata /view.

003_treefiles

1. Questa classe dovra’ quindi estendere il componente Panel.
2. Inizializziamo alcune variabili per il posizionamento del pulsante RESIZE all’interno della barra del titolo e impostiamo le dimensioni di default del componente (utilizzate all’interno del costruttore)
3. Definiamo infine il pulsante resize che sara’ istanziato successivamente

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package view
{
 
	import mx.containers.Panel;
	import mx.controls.Button;
	import flash.events.MouseEvent;
 
 
	public class ExtendedPanel extends Panel
	{
		// Inizializzazioni	
		private var marginRight:uint = 10;	
		private var marginTop:uint = 5;
		public var panelWidth:uint = 200;
		public var panelHeight:uint = 100;
 
		// Pulsante RESIZE presente nella TitleBar
		private var resize:Button;
 
		// Costruttore
		public function ExtendedPanel()
		{
			// Dimensioni di default
			this.width = panelWidth;
			this.height = panelHeight;
		}
 
 
	}
}

NOTA: per semplicita’ definiamo i valori delle proprieta’ del componente Panel e del pulsante RESIZE all’interno della classe stessa ma sarebbe buona norma creare dei metodi pubblici setters affinche’ queste proprieta’ siano definite dall’esterno, ad esempio direttamente dal codice MXML che istanzia il componente.





rawChildren, createChildren, updateDisplayList e override di metodi

Finora non abbiamo fatto nulla di particolare ma di seguito dovremo invece ridefinire alcuni metodi del componente Panel. In gergo questa operazione viene chiamata override di un metodo.




CREATECHILDREN()

Il primo metodo che dobbiamo riscrivere e’ il metodo createChildren, tramite il quale sara’ possibile inizializzare il nostro pulsante di resize e i relativi listener.

Il codice e’ abbastanza semplice da intuire ed evidenziamo solo alcune particolarita’:

1) Per ridefinire un metodo gia’ esistente dobbiamo utilizzare la keyword override ed e’ necessario che la tipologia del metodo (in questo caso protected) e il numero di parametri (in questo caso nessuno) combacino esattamente con quello originale
2) E’ necessario inoltre chiamare il metodo createChildren della classe originale tramite l’istruzione super.createChildren()
3) Sfruttiamo la proprieta’ rawChildren, per inserire elementi all’interno della chrome area
4) Da notare che a questo punto il pulsante non e’ stato ancora posizionato

1
2
3
4
5
6
7
8
9
10
11
12
// Inizializzazione pulsante RESIZE
protected override function createChildren():void {
    super.createChildren()
 
    resize = new Button();
    resize.label = "Res"
    resize.width = 50;
    resize.height= 20;
    resize.addEventListener(MouseEvent.CLICK, onClick)
    <strong>rawChildren.addChild(resize)</strong>	
 
}




UPDATEDISPLAYLIST()

Il secondo metodo che dobbiamo ridefinire e’ updateDisplayList() che si occupa invece di posizionare il pulsante alle coordinate desiderate.
Questo metodo saro’ invocato ogni qualvolta il componente verra’ ridimensionato, ad esempio quando le dimensioni del componente sono reimpostate tramite codice actionscript oppure quando il browser viene ridimensionato e restituisce due parametri, unscaledWidth e unscaledHeight, che rappresentano le dimensioni aggiornate del componente.

Come per il metodo precedente invochiamo la relativa superclass e successivamente calcoliamo le posizioni del componente: mentre la coordinata Y del pulsante e’ definita semplicemente tramite la variabile marginTop definita in precedenza, la coordinata X variera’ a seconda delle dimensioni del componente, dato che il nostro pulsante dovra’ essere posizionato sempre al margine destro del pannello.
Sfrutteremo quindi il parametro unscaledWidth per conoscere la dimensione del componente, al quale sottrarremo la dimensione del pulsante RESIZE e il margine destro definito all’inizio della classe.

1
2
3
4
5
6
7
8
9
10
11
12
// Posizionamento del pulsante
protected override function updateDisplayList(unscaledWidth:Number, 
                                              unscaledHeight:Number):void {
 
    super.updateDisplayList(unscaledWidth, unscaledHeight)
 
    // Posizione X del pulsante RESIZE al margine destro
    var x:Number = unscaledWidth - resize.width - marginRight;
    var y:Number = marginTop;
    resize.move(x, y)
 
}

Definiamo infine il metodo onClick che si occupera’ semplicemente di effettuare il resize del componente dalle dimensioni originali a 100% e viceversa.

1
2
3
4
5
6
7
8
9
10
11
12
private function onClick(e:MouseEvent):void {
 
    // Ridimensionamento del componento Panel 
    if (this.percentWidth == 100) {
        this.width = panelWidth;
        this.height= panelHeight;
    } else {
        this.percentWidth = 100;
        this.percentHeight = 100;
    }
 
}

NOTA: al posto di definire le funzionalita’ del CLICK all’interno del componente potrebbe essere utile effettuare un dispatch dell’evento CLICK affinche’ le funzionalita’ siano invece definite dall’esterno (vedi tutorial Estendere il componente Combobox in AS3 per caricare dati XML). In questo modo sara’ possibile associare diversi comportamenti, sfruttando questo componente in diverse circostanze





IL CODICE COMPLETO

Per utilizzare il componente sara’ sufficiente creare un nuovo file MXML e inserire il seguente codice

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" 
	xmlns:view="view.*">
 
	<view:ExtendedPanel title="Test Chrome">
		<mx:Text text="Layout Area" />
	</view:ExtendedPanel>
 
</mx:Application>

Di seguito il codice completo della classe ExtendedPanel.as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package view
{
 
	import mx.containers.Panel;
	import mx.controls.Button;
	import flash.events.MouseEvent;
 
 
	public class ExtendedPanel extends Panel
	{
		// Distanza pulsante dal margine destro del componente
		private var marginRight:uint = 10;			
 
		// Distanza pulsante RESIZE dal margine superiore
		private var marginTop:uint = 5;				
 
		// Dimensioni di default del pannello
		public var panelWidth:uint = 200;
		public var panelHeight:uint = 100;
 
		// Pulsante RESIZE presente nella TitleBar
		private var resize:Button;
 
 
 
		// Costruttore
		public function ExtendedPanel()
		{
			// Dimensioni di default
			this.width = panelWidth;
			this.height = panelHeight;
		}
 
 
 
		// Inizializzazione pulsante RESIZE
		protected override function createChildren():void {
 
			super.createChildren()
 
			resize = new Button();
			resize.label = "Res"
			resize.width = 50;
			resize.height= 20;
			resize.addEventListener(MouseEvent.CLICK, onClick)
			rawChildren.addChild(resize)	
 
		}
 
 
		// Posizionamento del pulsante
		protected override function updateDisplayList(unscaledWidth:Number, 
													  unscaledHeight:Number):void {
 
			super.updateDisplayList(unscaledWidth, unscaledHeight)
 
			// Posizione X del pulsante RESIZE al margine destro
			var x:Number = unscaledWidth - resize.width - marginRight;
			var y:Number = marginTop;
			resize.move(x, y)
 
		}
 
 
		private function onClick(e:MouseEvent):void {
 
			// Ridimensionamento del componento Panel 
			if (this.percentWidth == 100) {
				this.width = panelWidth;
				this.height= panelHeight;
			} else {
				this.percentWidth = 100;
				this.percentHeight = 100;
			}
 
		}
 
	}
}

Download Source Code

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.