Wednesday, October 19, 2011

Creating a Flex AIR text editor: Part 9

In this tutorial we will populate the font window with content.

In the previous tutorial we've set up a separate window for font settings that we can open, close and reopen. Now, let's add some font-related content in it! In this tutorial, we are only updating the FontWindow.mxml file.

Firstly, set the window dimensions and make it unresizable. I chose to make it 400 pixels wide and 550 pixels high:

<mx:Window xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns:mx="library://ns.adobe.com/flex/mx"
title="Font settings" type="utility" width="400" height="550"
creationComplete="init();" showStatusBar="false" alwaysInFront="true" resizable="false">

Now add a VGroup container which will hold all the things we're adding:

<s:VGroup paddingLeft="5" paddingRight="5" paddingTop="5" paddingBottom="5">
</s:VGroup>

Now we can add a List object, which will display all the installed local fonts. All the font names will also be displayed in that specific font ("Arial" displays in Arial font, "Times New Roman" displays in Times New Roman font, etc.). Set the dataProvider property of this List object to an allFonts ArrayCollection (which we will add shortly), labelField to fontName and make sure variableRowHeight is set to true.

Create a custom itemRenderer for the List, and make it a Label object, which has its fontFamily property set to data.fontName and toolTip property set to data.fontName too.

<s:Label text="Font:" />

<mx:List id="fontCombo" dataProvider="{allFonts}" labelField="fontName" fontSize="12" rowCount="8" variableRowHeight="true" width="380">
        <mx:itemRenderer>
            <fx:Component>
                <mx:Label fontFamily="{data.fontName}" toolTip="{data.fontName}"/>
            </fx:Component>
        </mx:itemRenderer>
    </mx:List>

Now, we need to go back a little and create this allFonts ArrayCollection which will contain all the local fonts. Open Declarations tags and create the collection with source set to{ Font.enumerateFonts(true)}. I also sort the fonts alphabetically:

<fx:Declarations>
<mx:ArrayCollection id="allFonts"
            source="{Font.enumerateFonts(true)}">
        <mx:sort>
            <mx:Sort>
                <mx:fields>
                    <mx:SortField name="fontName" />
                </mx:fields>
            </mx:Sort>
        </mx:sort>
    </mx:ArrayCollection>
</fx:Declarations>

Now, let's get back to adding more content.

Now that we have a list which displays all the fonts, we can create another List which will be responsible for displaying font styles. There can be 4 font styles - regular, italic, bold, bold and italic. Set the dataProvider to a fontStyles array, labelField to label, variableRowHeight to true. Create a custom itemRenderer for this list, add a Label object inside. Set the label's fontFamily property to the fontName of the selected item of the fontCombo combobox ,toolTip to data.label, fontStyle to data.fontstyle and fontWeight to data.fontweight.

We need to use both fontStyle and fontWeight properties, because fontStyle is responsible for italic (values: normal or italic), while fontWeight is responsible for boldness (values: normal or bold).

<s:Label text="Font style:" />

<mx:List id="styleCombo" dataProvider="{fontStyles}" labelField="label" fontSize="12" rowCount="4" variableRowHeight="true" width="380">
        <mx:itemRenderer>
            <fx:Component>
                <mx:Label fontFamily="{outerDocument.fontCombo.selectedItem.fontName}" toolTip="{data.label}" fontStyle="{data.fontstyle}" fontWeight="{data.fontweight}" />
            </fx:Component>
        </mx:itemRenderer>
    </mx:List>

Go back to declarations, add another array collection:

<mx:ArrayCollection id="fontStyles">
<fx:Object label="Regular" fontstyle="normal" fontweight="normal" />
<fx:Object label="Italic" fontstyle="italic" fontweight="normal"/>
<fx:Object label="Bold" fontstyle="normal" fontweight="bold"/>
<fx:Object label="Bold Italic" fontstyle="italic" fontweight="bold"/>
</mx:ArrayCollection>

Now it works.

Let's add more items, specifically - a numericstepper for font size, a colorpicker for font color and a colorpicker for background color:

<s:HGroup verticalAlign="middle">
<s:Label text="Font size:" /><mx:NumericStepper id="sizeStepper" minimum="2" maximum="72" />
<s:Label text="Font color:" /><mx:ColorPicker id="colorPicker"/>
<s:Label text="Background color:" /><mx:ColorPicker id="bgColorPicker"/>
</s:HGroup>

Now we can add a little Sample area, which shows the user how the text is going to look like. We will need to use a Box container for this one, because we also want to show and change the background color behind the text. In the box, create a Label object, setting all its font-related properties to the values of the respective setting controls in this window.

<s:Label text="Sample:" />
<mx:Box backgroundColor="{bgColorPicker.selectedColor}" width="370" height="70" paddingLeft="5" paddingTop="5">
<s:Label fontFamily="{fontCombo.selectedItem.fontName}" fontSize="{sizeStepper.value}" 
color="{colorPicker.selectedColor}" fontStyle="{styleCombo.selectedItem.fontstyle}" 
fontWeight="{styleCombo.selectedItem.fontweight}" text="AaBbYyZz"/>
</mx:Box>

The text now displays the way it will later display in the program, according to the font settings.

Finally, add an Apply button.

<s:Button label="Apply settings"/>

Full code for the FontWindow.mxml document:

<?xml version="1.0" encoding="utf-8"?>
<mx:Window xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns:mx="library://ns.adobe.com/flex/mx"
title="Font settings" type="utility" width="400" height="550"
creationComplete="init();" showStatusBar="false" alwaysInFront="true" resizable="false">

<fx:Declarations>
<mx:ArrayCollection id="allFonts"
            source="{Font.enumerateFonts(true)}">
        <mx:sort>
            <mx:Sort>
                <mx:fields>
                    <mx:SortField name="fontName" />
                </mx:fields>
            </mx:Sort>
        </mx:sort>
    </mx:ArrayCollection>
<mx:ArrayCollection id="fontStyles">
<fx:Object label="Regular" fontstyle="normal" fontweight="normal" />
<fx:Object label="Italic" fontstyle="italic" fontweight="normal"/>
<fx:Object label="Bold" fontstyle="normal" fontweight="bold"/>
<fx:Object label="Bold Italic" fontstyle="italic" fontweight="bold"/>
</mx:ArrayCollection>
</fx:Declarations>

<fx:Script>
<![CDATA[
import flash.events.Event;
import mx.controls.Alert;

private function init():void{
this.addEventListener(Event.CLOSING, onClose);
}

private function onClose(evt:Event):void {
this.visible = false;
evt.preventDefault();
}
]]>
</fx:Script>

<s:VGroup paddingLeft="5" paddingRight="5" paddingTop="5" paddingBottom="5">
<s:Label text="Font:" />

<mx:List id="fontCombo" dataProvider="{allFonts}" labelField="fontName" fontSize="12" rowCount="8" variableRowHeight="true" width="380">
        <mx:itemRenderer>
            <fx:Component>
                <mx:Label fontFamily="{data.fontName}" toolTip="{data.fontName}"/>
            </fx:Component>
        </mx:itemRenderer>
    </mx:List>

<s:Label text="Font style:" />

<mx:List id="styleCombo" dataProvider="{fontStyles}" labelField="label" fontSize="12" rowCount="4" variableRowHeight="true" width="380">
        <mx:itemRenderer>
            <fx:Component>
                <mx:Label fontFamily="{outerDocument.fontCombo.selectedItem.fontName}" toolTip="{data.label}" fontStyle="{data.fontstyle}" fontWeight="{data.fontweight}" />
            </fx:Component>
        </mx:itemRenderer>
    </mx:List>

<s:HGroup verticalAlign="middle">
<s:Label text="Font size:" /><mx:NumericStepper id="sizeStepper" minimum="2" maximum="72" />
<s:Label text="Font color:" /><mx:ColorPicker id="colorPicker"/>
<s:Label text="Background color:" /><mx:ColorPicker id="bgColorPicker"/>
</s:HGroup>

<s:Label text="Sample:" />
<mx:Box backgroundColor="{bgColorPicker.selectedColor}" width="370" height="70" paddingLeft="5" paddingTop="5">
<s:Label fontFamily="{fontCombo.selectedItem.fontName}" fontSize="{sizeStepper.value}" 
color="{colorPicker.selectedColor}" fontStyle="{styleCombo.selectedItem.fontstyle}" 
fontWeight="{styleCombo.selectedItem.fontweight}" text="AaBbYyZz"/>
</mx:Box>

<s:Button label="Apply settings"/>
</s:VGroup>

</mx:Window>

Thanks for reading!

No comments:

Post a Comment