Wednesday, November 2, 2011

Creating a Flex AIR text editor: Part 23

In this tutorial we are going to add icons to our application!

Here's what the program is going to look like by the end of this tutorial:



The icons used here are from a free icons set called Silk icons by Famfamfam. You can use them as well!

I downloaded the silk pack and then selected some icons I want to use in my appication and put them into the lib folder of my project.

First, let's add the paper (page.png) icon and the close (cross.png) icon for each tab in the tabbar.

Open CustomTab.mxml, add a BitmapImage (or an Image) object before the labelDisplay label, set its source to the page.png file (if you have icons in the lib folder, which is outside the src folder, which contains all mxml files, your path will look like mine):

<s:BitmapImage source="@Embed('../lib/page.png')" top="3" left="4" />

Set the label's position so that it doesn't overlap with the image. I also set its text align to left because I like it better that way:

    <s:Label
        id="labelDisplay"
        textAlign="left"
        verticalAlign="middle"
        maxDisplayedLines="1"
        horizontalCenter="0"
        verticalCenter="1"
        left="24"
        right="20"
        top="2"
        bottom="2"
    />

Now change the existing X button label to an Image object containing the cross icon:

<mx:Image source="@Embed('../lib/cross.png')" top="3" right="4" id="labelClose" click="labelClose_clickHandler(event)" useHandCursor="true" buttonMode="true"/>

Your CustomTab.mxml file now looks like this:

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        width="100%"
        height="100"
        autoDrawBackground="false"
>   

    <fx:Metadata>
        [Event(name="tabClose")]
    </fx:Metadata>

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

        private var tab:*;
        override public function set data(value:Object):void
        {
            super.data = value;
            tab = value;
        }

        override protected function updateDisplayList(w:Number, h:Number):void
        {
            super.updateDisplayList(w,h);
            if (labelDisplay)
            {
                labelDisplay.text = (data.saved)?(data.title):(data.title + "*");
            }
        }              

        protected function labelClose_clickHandler(event:MouseEvent):void
        {
            event.stopImmediatePropagation();
dispatchEvent(new Event("tabClose", true));
        }

    ]]>
    </fx:Script>
   
    <s:states>
        <s:State name="normal" basedOn="{data.state}"/>
        <s:State name="selected" basedOn="{data.state}"/>
        <s:State name="hovered" basedOn="{data.state}"/>
    </s:states>

    <!-- background -->
    <s:Rect left="1" right="1" top="1" bottom="0">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0xffffff" />
                <s:GradientEntry
                    color="0xd8d8d8"
                    alpha="0.85"
                    color.selected="0xffffff"
                    alpha.selected="1.0"
                    color.hovered="0x929496"
                    alpha.hovered="0.85"
                />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>

    <!-- border rectangle -->
    <s:Line left="0" right="0" top="1">
        <s:stroke>
            <s:SolidColorStroke
                weight="1"
                alpha="1.0"
                color="0x999999"
            />
        </s:stroke>
    </s:Line>
    <s:Line left="0" bottom="0" top="1">
        <s:stroke>
            <s:SolidColorStroke
                weight="1"
                alpha="1.0"
                color="0x999999"
            />
        </s:stroke>
    </s:Line>
    <s:Line right="0" bottom="0" top="1">
        <s:stroke>
            <s:SolidColorStroke
                weight="1"
                alpha="1.0"
                color="0x999999"
            />
        </s:stroke>
    </s:Line>
    <s:Line left="0" right="0" bottom="0">
        <s:stroke>
            <s:SolidColorStroke
                weight="1"
                alpha="1.0"
                color="0x999999"
                alpha.selected="0.0"
                color.selected="0xffffff"
            />
        </s:stroke>
    </s:Line>

<s:BitmapImage source="@Embed('../lib/page.png')" top="3" left="4" />
   
    <s:Label
        id="labelDisplay"
        textAlign="left"
        verticalAlign="middle"
        maxDisplayedLines="1"
        horizontalCenter="0"
        verticalCenter="1"
        left="24"
        right="20"
        top="2"
        bottom="2"
    />

<mx:Image source="@Embed('../lib/cross.png')" top="3" right="4" id="labelClose" click="labelClose_clickHandler(event)" useHandCursor="true" buttonMode="true"/>

</s:ItemRenderer>

Now, go to CustomListItem.mxml, we will add the icons here too. Basically do the same things you did with the previous file, just make sure it is positioned nicely:

<s:BitmapImage source="@Embed('../lib/page.png')" top="2" left="2" />
<s:Label id="labelDisplay" left="25" right="20" top="4" bottom="4" />
<mx:Image source="@Embed('../lib/cross.png')" top="2" right="4" id="closeButton" click="labelClose(event)" useHandCursor="true" buttonMode="true"/>

Full CustomListItem.mxml code:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/01/27/creating-a-fancy-spark-list-control-item-renderer-in-flex-4/ -->
<s:ItemRenderer name="CustomListItemRenderer"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
        autoDrawBackground="true" >

<fx:Script>
<![CDATA[
import flash.events.MouseEvent;
import flash.events.Event;

override protected function updateDisplayList(w:Number, h:Number):void {
super.updateDisplayList(w, h);
if(labelDisplay){
labelDisplay.text = (data.saved)?(data.title):(data.title + "*");
}
}

private function labelClose(evt:MouseEvent):void {
evt.stopImmediatePropagation();
dispatchEvent(new Event("tabClose", true));
}
]]>
</fx:Script>

    <fx:Metadata>
        [Event(name="tabClose")]
    </fx:Metadata>

<s:BitmapImage source="@Embed('../lib/page.png')" top="2" left="2" />
<s:Label id="labelDisplay" left="25" right="20" top="4" bottom="4" />
<mx:Image source="@Embed('../lib/cross.png')" top="2" right="4" id="closeButton" click="labelClose(event)" useHandCursor="true" buttonMode="true"/>
</s:ItemRenderer>

Now, let's add icons to our side pane in the Main.mxml file.

There's this group in the sidePan Box control which contains the 'Tab management' text and an X button label, remove the second label and replace it with an icon. I chose bullet_go.png for this one:

<s:Group>
<s:Label text="Tab management" width="{sidePaneWidth}" />
<mx:Image source="@Embed('../lib/bullet_go.png')" top="-4" right="15" click="closeSidePane();" useHandCursor="true" buttonMode="true"/>
</s:Group>

Now, let's add a ToggleButtonBar to our side pane. It will be used to change the side pane's content (Tab management, File browsing and Snippets). The icons that I chose for these buttons are page.png, folder_magnify.png and book.png. Before we add the icons, though, we need to add the button bar. Set its dataProvider to a sidePaneData array collection and iconField to icon.

<mx:ToggleButtonBar dataProvider="{sidePaneData}" iconField="icon" width="{sidePaneWidth-10}"/>

Now create the ArrayCollection in the Declarations tags. Add 3 objects with icon properties, set those properties to the embedded urls to the icons:

<mx:ArrayCollection id="sidePaneData">
<fx:Object icon="@Embed('../lib/page.png')" />
<fx:Object icon="@Embed('../lib/folder_magnify.png')" />
<fx:Object icon="@Embed('../lib/book.png')" />
</mx:ArrayCollection>

Full code:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       xmlns:mx="library://ns.adobe.com/flex/mx"
   xmlns:custom="*"
   creationComplete="init();" title="Kirpad" showStatusBar="{pref_status}"
   minWidth="400" minHeight="200" height="700" width="900">
   
<s:menu>
<mx:FlexNativeMenu dataProvider="{windowMenu}" showRoot="false" labelField="@label" keyEquivalentField="@key" itemClick="menuSelect(event);" />
</s:menu>

<fx:Script>
<![CDATA[
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.NativeWindowBoundsEvent;
import flash.net.SharedObject;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.FlexNativeMenuEvent;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.elements.Configuration;
import flash.system.System;
import flash.desktop.Clipboard;
import flash.desktop.ClipboardFormats;
import flash.ui.Mouse;
import mx.events.CloseEvent;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;
import flash.events.ContextMenuEvent;
import mx.events.ResizeEvent;
import mx.core.FlexGlobals;

private var preferences:SharedObject = SharedObject.getLocal("kirpadPreferences");
[Bindable]
private var pref_wrap:Boolean = true;
[Bindable]
private var pref_status:Boolean = true;
[Bindable]
private var pref_toolbar:Boolean = true;
[Bindable]
private var pref_sidepane:Boolean = true;
[Bindable]
public var pref_fontsettings:Object = new Object();

private var initHeight:Number;
private var heightFixed:Boolean = false;

private var statusMessage:String;
[Bindable]
private var textHeight:Number;
[Bindable]
private var textWidth:Number;
[Bindable]
private var textY:Number;
[Bindable]
private var tabY:Number;
[Bindable]
private var sidePaneY:Number;
[Bindable]
private var sidePaneX:Number;
[Bindable]
private var sidePaneHeight:Number;
[Bindable]
private var sidePaneWidth:Number = 180;
[Bindable]
private var sideContentWidth:Number = 170;

[Bindable]
private var tabSelectedIndex:int = 0;

private var previousIndex:int = 0;
private var rightclickTabIndex:int = 0;
private var untitledNum:int = 0;
private var tabsToClose:int = 0;
private var closeAfterConfirm:Boolean = false;

public var fontWindow:FontWindow = new FontWindow();

private function init():void {

// Create a listener for every frame
addEventListener(Event.ENTER_FRAME, everyFrame);

// Set initHeight to the initial height value on start
initHeight = height;

// Set preferences if loaded for the first time
if (preferences.data.firsttime == null) {
preferences.data.firsttime = true;
preferences.data.wrap = true;
preferences.data.status = true;
preferences.data.toolbar = true;
preferences.data.sidepane = true;
preferences.data.fontsettings = {fontfamily:"Lucida Console", fontsize:14, fontstyle:"normal", fontweight:"normal", fontcolor:0x000000, bgcolor:0xffffff};
preferences.flush();
}

// Set preferences loaded from local storage
pref_wrap = preferences.data.wrap;
pref_status = preferences.data.status;
pref_toolbar = preferences.data.toolbar;
pref_sidepane = preferences.data.sidepane;
pref_fontsettings = preferences.data.fontsettings;

// Allow insertion of tabs
var textFlow:TextFlow = textArea.textFlow;
var config:Configuration = Configuration(textFlow.configuration);
config.manageTabKey = true;

// Set status message
statusMessage = "[ " + new Date().toLocaleTimeString() + " ] Kirpad initialized";
updateStatus();

// Close all sub-windows if main window is closed
addEventListener(Event.CLOSING, onClose);

// Add listener for the event that is dispatched when new font settings are applied
fontWindow.addEventListener(Event.CHANGE, fontChange);

// Update real fonts with the data from the settings values
updateFonts();

// Create a listener for resizing
addEventListener(NativeWindowBoundsEvent.RESIZE, onResize);

// Context menu declaration for the tabbar control
var cm_close:ContextMenuItem = new ContextMenuItem("Close tab");
cm_close.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, tabContextClose);
var cm_closeother:ContextMenuItem = new ContextMenuItem("Close other tabs");
cm_closeother.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, tabContextCloseOther);

var cm:ContextMenu = new ContextMenu();
cm.items = [cm_close, cm_closeother];
cm.hideBuiltInItems();
tabBar.contextMenu = cm;
tabBar.addEventListener(MouseEvent.RIGHT_MOUSE_DOWN, tabRightClick);

// Listen to keyboard
addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}

private function menuSelect(evt:FlexNativeMenuEvent):void {
(evt.item.@label == "New")?(doNew()):(void);
(evt.item.@label == "Word wrap")?(pref_wrap = !pref_wrap):(void);
(evt.item.@label == "Cut")?(doCut()):(void);
(evt.item.@label == "Copy")?(doCopy()):(void);
(evt.item.@label == "Paste")?(doPaste()):(void);
(evt.item.@label == "Select all")?(doSelectall()):(void);
(evt.item.@label == "Status bar")?(pref_status = !pref_status):(void);
(evt.item.@label == "Tool bar")?(pref_toolbar = !pref_toolbar):(void);
(evt.item.@label == "Side pane")?(pref_sidepane = !pref_sidepane):(void);
(evt.item.@label == "Font...")?(doFont()):(void);
savePreferences();
updateStatus();
updateTextSize();
}

private function savePreferences():void {
preferences.data.wrap = pref_wrap;
preferences.data.status = pref_status;
preferences.data.toolbar = pref_toolbar;
preferences.data.fontsettings = pref_fontsettings;
preferences.data.sidepane = pref_sidepane;
preferences.flush();
}

private function doCut():void {
var selectedText:String = textArea.text.substring(textArea.selectionActivePosition, textArea.selectionAnchorPosition);
System.setClipboard(selectedText);
insertText("");
}

private function doCopy():void {
var selectedText:String = textArea.text.substring(textArea.selectionActivePosition, textArea.selectionAnchorPosition);
System.setClipboard(selectedText);
}

private function doPaste():void{
var myClip:Clipboard = Clipboard.generalClipboard;
var pastedText:String = myClip.getData(ClipboardFormats.TEXT_FORMAT) as String;
insertText(pastedText);
}

private function doSelectall():void {
textArea.selectAll();
}

private function insertText(str:String):void {
var substrPositions:int = textArea.selectionActivePosition - textArea.selectionAnchorPosition;
var oldSel1:int = (substrPositions>0)?(textArea.selectionAnchorPosition):(textArea.selectionActivePosition);
var oldSel2:int = (substrPositions<0)?(textArea.selectionAnchorPosition):(textArea.selectionActivePosition);
var preText:String = textArea.text.substring(0, oldSel1);
var postText:String = textArea.text.substring(oldSel2);
var newSelectRange:int = preText.length + str.length;
textArea.text = preText + str + postText;
textArea.selectRange(newSelectRange, newSelectRange);
}

private function cursorFix():void{
Mouse.cursor = "ibeam";
}

private function everyFrame(evt:Event):void {
if (!heightFixed && height==initHeight) {
height = initHeight - 20;
if (height != initHeight) {
heightFixed = true;
updateTextSize();
}
}
}

private function onResize(evt:ResizeEvent):void {
updateTextSize();
}

private function updateTextSize():void {
tabY = (toolBar.visible)?(toolBar.height):(0);
textY = tabBar.height + tabY;
var statusHeight:Number = (pref_status)?(statusBar.height):(0);
textHeight = height - textY - statusHeight;
textWidth = (pref_sidepane)?(width - sidePaneWidth):(width);
focusManager.setFocus(textArea);
sidePaneHeight = textHeight + tabBar.height;
sidePaneY = textY-tabBar.height;
sidePaneX = width - sidePaneWidth;
}

private function updateStatus():void {
var str:String = new String();
str = (pref_wrap)?("Word wrapping on"):(caretPosition());
status = str + "\t" + statusMessage;
}

private function caretPosition():String {
var pos:int = textArea.selectionActivePosition;
var str:String = textArea.text.substring(0, pos);
var lines:Array = str.split("\n");
var line:int = lines.length;
var col:int = lines[lines.length - 1].length + 1;

return "Ln " + line + ", Col " + col;
}

private function doFont():void{
fontWindow.open();
fontWindow.activate();
fontWindow.visible = true;
fontWindow.setValues(pref_fontsettings.fontsize, pref_fontsettings.fontfamily, pref_fontsettings.fontstyle, pref_fontsettings.fontweight, pref_fontsettings.fontcolor, pref_fontsettings.bgcolor);
}

private function onClose(evt:Event):void {
if(!closeAfterConfirm){
evt.preventDefault();
var allWindows:Array = NativeApplication.nativeApplication.openedWindows;
for (var i:int = 1; i < allWindows.length; i++)
{
allWindows[i].close();
}

// Check if there are any unsaved tabs
var needSaving:Boolean = false;
tabsToClose = 0;

for (var u:int = 0; u < tabData.length; u++) {
if (tabData[u].saved == false) {
needSaving = true;
tabsToClose++;
}
}

// If there are unsaved tabs, dont close window yet, set closeAfterConfirm to true and close all tabs
if (needSaving) {
closeAfterConfirm = true;
for (var t:int = 0; t < tabData.length; t++) {
closeTab(t);
}
}
if (!needSaving) {
FlexGlobals.topLevelApplication.close();
}
}
}

private function fontChange(evt:Event):void{
pref_fontsettings.fontfamily = fontWindow.fontCombo.selectedItem.fontName;
pref_fontsettings.fontsize = fontWindow.sizeStepper.value;

if (fontWindow.styleCombo.selectedIndex == 0) {
pref_fontsettings.fontstyle = "normal";
pref_fontsettings.fontweight = "normal";
}
if (fontWindow.styleCombo.selectedIndex == 1) {
pref_fontsettings.fontstyle = "italic";
pref_fontsettings.fontweight = "normal";
}
if (fontWindow.styleCombo.selectedIndex == 2) {
pref_fontsettings.fontstyle = "normal";
pref_fontsettings.fontweight = "bold";
}
if (fontWindow.styleCombo.selectedIndex == 3) {
pref_fontsettings.fontstyle = "italic";
pref_fontsettings.fontweight = "bold";
}

pref_fontsettings.fontcolor = fontWindow.colorPicker.selectedColor;
pref_fontsettings.bgcolor = fontWindow.bgColorPicker.selectedColor;

savePreferences();
updateFonts();
}

private function updateFonts():void{
textArea.setStyle("fontFamily", pref_fontsettings.fontfamily);
textArea.setStyle("fontSize", pref_fontsettings.fontsize);
textArea.setStyle("fontStyle", pref_fontsettings.fontstyle);
textArea.setStyle("fontWeight", pref_fontsettings.fontweight);
textArea.setStyle("color", pref_fontsettings.fontcolor);
textArea.setStyle("contentBackgroundColor", pref_fontsettings.bgcolor);
}

private function onTabClose(evt:Event):void {
var tabWidth:Number = tabBar.width / tabData.length;
var cIndex:int = Math.floor(tabBar.mouseX / tabWidth);
tabSelectedIndex = cIndex;
tabChange();
closeTab(tabSelectedIndex);
}

private function onListClose(evt:Event):void {
tabSelectedIndex = sideList.selectedIndex;
tabChange();
closeTab(tabSelectedIndex);
}

private function closeTab(index:int):void {
if (tabData[index].saved) {
removeTab(index);
}
if (!tabData[index].saved) {
Alert.show("Save " + tabData[index].title + " before closing?", "Confirmation", Alert.YES | Alert.NO, null, confirmClose);
}
function confirmClose(evt:CloseEvent):void {
tabsToClose--;
if (evt.detail == Alert.YES) {
// TODO: call saving function here
removeTab(index);
}else {
removeTab(index);
}
}
}

private function removeTab(index:int):void {
// if this is the last tab, create a new empty tab
if (tabData.length == 1) {
tabData.addItem( { title:"Untitled", textData:"", saved:false } );
}
statusMessage = "[ " + new Date().toLocaleTimeString() + " ] Tab closed: " + tabData[index].title;
updateStatus();
tabData.removeItemAt(index);
tabSelectedIndex = tabBar.selectedIndex;
previousIndex = tabSelectedIndex;
textArea.text = tabData[tabSelectedIndex].textData;
textArea.selectRange(tabData[tabSelectedIndex].selectedAnchor, tabData[tabSelectedIndex].selectedActive);
if (closeAfterConfirm && tabsToClose == 0) {
FlexGlobals.topLevelApplication.close();
}
}

private function doNew():void {
statusMessage = "[ " + new Date().toLocaleTimeString() + " ] New tab created";
updateStatus();
untitledNum++;
tabData.addItem( { title:"Untitled("+untitledNum+")", textData:"", saved:false } );
tabSelectedIndex = tabData.length - 1;
tabChange();
}

private function tabChange(from:String = "none"):void {
if (from == "tabbar") {
tabSelectedIndex = tabBar.selectedIndex;
}
if (from == "sidelist") {
tabSelectedIndex = sideList.selectedIndex;
}
tabData[previousIndex].textData = textArea.text;
tabData[previousIndex].selectedActive = textArea.selectionActivePosition;
tabData[previousIndex].selectedAnchor = textArea.selectionAnchorPosition;
previousIndex = tabSelectedIndex;
textArea.text = tabData[tabSelectedIndex].textData;
textArea.selectRange(tabData[tabSelectedIndex].selectedAnchor, tabData[tabSelectedIndex].selectedActive);
updateStatus();
}

private function tabContextClose(evt:ContextMenuEvent):void{
closeTab(rightclickTabIndex);
}

private function tabContextCloseOther(evt:ContextMenuEvent):void {
var len:int = tabData.length;
for (var i:int = 0; i < len; i++) {
if (i != rightclickTabIndex) {
closeTab(i);
}
}
}

private function tabRightClick(evt:MouseEvent):void {
var tabWidth:Number = tabBar.width / tabData.length;
var rcIndex:int = Math.floor(tabBar.mouseX / tabWidth);
rightclickTabIndex = rcIndex;
}

private function onKeyDown(evt:KeyboardEvent):void{
if (evt.ctrlKey) {
// Ctrl+TAB - next tab
if (evt.keyCode == 9 && !evt.shiftKey) {
if (tabData.length - tabSelectedIndex > 1) {
tabSelectedIndex++;
tabChange();
}
}
// Ctrl+Shift+TAB - previous tab
if (evt.keyCode == 9 && evt.shiftKey) {
if (tabSelectedIndex > 0) {
tabSelectedIndex--;
tabChange();
}
}
// Ctrl+number (1-8) - go to numbered tab
if (evt.keyCode >= 49 && evt.keyCode <= 56) {
var num:int = evt.keyCode - 48;
if (tabData.length > num - 1) {
tabSelectedIndex = num - 1;
tabChange();
}
}
// Ctrl+9 - go to last tab
if (evt.keyCode == 57) {
tabSelectedIndex = tabData.length - 1;
tabChange();
}
}
}

private function closeSidePane():void{
pref_sidepane = !pref_sidepane
savePreferences();
updateTextSize();
}
]]>
</fx:Script>

<fx:Declarations>
<fx:XML id="windowMenu">
<root>
<menuitem label="File">
<menuitem label="New" key="n" controlKey="true" />
<menuitem label="Open" key="o" controlKey="true" />
</menuitem>
<menuitem label="Edit">
<menuitem label="Cut" key="x" controlKey="true" />
<menuitem label="Copy" key="c" controlKey="true" />
<menuitem label="Paste" key="v" controlKey="true" />
<menuitem type="separator"/>
<menuitem label="Select all" key="a" controlKey="true" />
</menuitem>
<menuitem label="Settings">
<menuitem label="Word wrap" type="check" toggled="{pref_wrap}" />
<menuitem label="Font..."/>
</menuitem>
<menuitem label="View">
<menuitem label="Tool bar" type="check" toggled="{pref_toolbar}" />
<menuitem label="Status bar" type="check" toggled="{pref_status}" />
<menuitem label="Side pane" type="check" toggled="{pref_sidepane}" />
</menuitem>
</root>
</fx:XML>
<mx:ArrayCollection id="tabData">
<fx:Object title="Untitled" textData="" saved="false" seletedActive="0" selectedAnchor="0" />
</mx:ArrayCollection>
<mx:ArrayCollection id="sidePaneData">
<fx:Object icon="@Embed('../lib/page.png')" />
<fx:Object icon="@Embed('../lib/folder_magnify.png')" />
<fx:Object icon="@Embed('../lib/book.png')" />
</mx:ArrayCollection>
</fx:Declarations>

<s:Group width="100%" height="100%">
<s:TextArea id="textArea" width="{textWidth}" height="{textHeight}" y="{textY}" borderVisible="false" lineBreak="{(pref_wrap)?('toFit'):('explicit')}"  click="cursorFix(); updateStatus();" change="updateStatus();" keyDown="updateStatus();"/>
<custom:CustomTabBar id="tabBar" dataProvider="{tabData}" width="{textWidth}" y="{tabY}" itemRenderer="CustomTab" height="22" tabClose="onTabClose(event);" change="tabChange('tabbar');" selectedIndex="{tabSelectedIndex}"/>
<mx:Box id="toolBar" width="100%" backgroundColor="#dddddd" height="24" visible="{pref_toolbar}">
</mx:Box>
<mx:Box id="sidePane" width="{sidePaneWidth}" y="{sidePaneY}" x="{sidePaneX}" height="{sidePaneHeight}" backgroundColor="#dddddd" visible="{pref_sidepane}" paddingTop="5" paddingLeft="5" horizontalScrollPolicy="off">
<s:Group>
<s:Label text="Tab management" width="{sidePaneWidth}" />
<mx:Image source="@Embed('../lib/bullet_go.png')" top="-4" right="15" click="closeSidePane();" useHandCursor="true" buttonMode="true"/>
</s:Group>
<mx:ToggleButtonBar dataProvider="{sidePaneData}" iconField="icon" width="{sidePaneWidth-10}"/>
<custom:CustomList id="sideList" dataProvider="{tabData}" width="{sideContentWidth}" height="100%" itemRenderer="CustomListItem" selectedIndex="{tabSelectedIndex}" change="tabChange('sidelist');" tabClose="onListClose(event);"/>
</mx:Box>
</s:Group>

</s:WindowedApplication>

Thanks for reading!

No comments:

Post a Comment