When you’re working with an application component and styles, the application component can define its own style values for components within it. The easiest way to specify such styles is to define Cascading Style Sheets (CSS) within the application component as you would within an application (however, you will still have the limitation of not being able to specify CSS type selectors other than in ActionScript). When working with styles within a component, keep in mind why application components exist. They don’t exist to be as fully featured and flexible as distributed components. They exist to allow you to build an application more efficiently. As such, you may find that defining styles within an application component is acceptable.
With application components, you can also define your own custom styles, as discussed in Chapter 19.
Also, as we saw in Chapter 8, styles in Flex support
inheritance, which is also supported by application components. When
defining a global style or CSS custom class, these styles are applied to
all display items in Flex. This allows you the benefit of providing one
master CSS file for an application. In the CSS file, you can define your
custom style, and for any component in your application you can apply the
style by setting the styleName
property.
In this example, we first set the styleName
property of the Label
component:
<mx:Label id="contactName" styleName="heading" x="10" y="10" text="John Doe"/>
Once the styleName
value is set,
we can define style values anywhere within our application, including
within the application component itself. Here a style definition is
created in an <mx:Style>
tag:
<mx:Style> .heading { font-size:16; font-weight:bold; } </mx:Style>
Application components can also define states internally. In the
ContactDetails
component, we want the
ability to support two modes: an edit mode and a view mode. By default,
the component will be in view mode, but with the public mode property
defined earlier in this chapter, a user can change the state of the ContactDetails
component easily.
First you define the states (we discuss this in more detail in Chapter 12):
<mx:states> <mx:State name="{VIEW_MODE}"/> <mx:State name="{EDIT_MODE}" basedOn="{VIEW_MODE}"> <mx:SetProperty target="{address}" name="editable" value="true"/> <mx:SetProperty target="{email}" name="editable" value="true"/> <mx:SetProperty target="{phone}" name="editable" value="true"/> </mx:State> </mx:states>
To set the default state of the component, you set the currentState
property of the root node of the ContactDetails
component:
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" backgroundColor=
"#f8f8f8" height="100%" currentState="view">
With the states defined, providing a mechanism to set the state is
easy. We just need to update the mode setter to set the component’s
currentState
property and the getter
to return the value of the currentState
property:
[Inspectable(enumeration="{ContactDetails.VIEW_MODE},{ContactDetails.EDIT_MODE}")] public function set mode(value:String):void { this.currentState = value; } [Bindable]public function get
mode():String {return this
.currentState; }
Declaring your own public API to set the component’s state isn’t
required, but it is a good practice. The currentState
property is declared publicly,
and defining your own setter with valid values reduces the likelihood
of errors and is a form of documentation that can help others use a
component.
Because we’ve been working on the code in snippets throughout the chapter, we thought it might help you to understand the utility of application components by providing you with the component code in its entirety:
<?xml version="1.0" encoding="utf-8"?> <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" backgroundColor= "#f8f8f8" height="100%" currentState="view"> <mx:Metadata> [Event(name="editChange", type="com.oreilly.programmingflex.contactmanager.events. EditChangeEvent")] </mx:Metadata> <mx:Script> <![CDATA[ import com.oreilly.programmingflex.contactmanager.events.EditChangeEvent; import mx.controls.Alert; import mx.states.State; public static const VIEW_MODE:String = "view"; public static const EDIT_MODE:String = "edit"; [Bindable] public function get mode():String { return this.currentState; } public function clear():void { address.text = null; phone.text = null; email.text = null; } [Inspectable(enumeration=" {ContactDetails.VIEW_MODE},{ContactDetails.EDIT_MODE}")] public function set mode(value:String):void { this.currentState = value; } private function clickHandler(e:Event):void { if(this.currentState == VIEW_MODE) { this.mode = EDIT_MODE; phone.setFocus(); var eventEditing:EditChangeEvent = new EditChangeEvent(true); dispatchEvent(eventEditing); } else if(this.currentState == EDIT_MODE) { this.mode = VIEW_MODE; var eventDoneEditing:EditChangeEvent = new EditChangeEvent(false); dispatchEvent(eventDoneEditing); } } ]]> </mx:Script> <mx:Style> .heading { font-size:16; font-weight:bold; } </mx:Style> <mx:states> <mx:State name="{VIEW_MODE}"/> <mx:State name="{EDIT_MODE}" basedOn="{VIEW_MODE}"> <mx:SetProperty target="{address}" name="editable" value="true"/> <mx:SetProperty target="{email}" name="editable" value="true"/> <mx:SetProperty target="{phone}" name="editable" value="true"/> </mx:State> </mx:states> <mx:Label id="contactName" styleName="heading" x="10" y="10" text="John Doe"/> <mx:Button id="edit" bottom="10" left="10" label="Edit" width="41" height="20" toggle="true" click="clickHandler(event)"/> <mx:Label x="62" y="42" text="phone"/> <mx:Label x="53" y="94" text="address"/> <mx:Label x="66" y="68" text="email"/> <mx:TextArea x="110" y="93" editable="false" enabled="true" width="160" height="63" id="address"/> <mx:TextInput x="110" y="40" editable="false" id="phone"/> <mx:TextInput x="110" y="66" editable="false" id="email"/> </mx:Canvas>