////////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package mx.controls
{
import flash.events.Event;
import flash.filesystem.File;
import flash.text.TextLineMetrics;
import mx.collections.CursorBookmark;
import mx.controls.ComboBox;
import mx.controls.fileSystemClasses.FileSystemComboBoxRenderer;
import mx.controls.fileSystemClasses.FileSystemControlHelper;
import mx.core.ClassFactory;
import mx.core.mx_internal;
import mx.events.FileEvent;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;
use namespace mx_internal;
//--------------------------------------
// Excluded APIs
//--------------------------------------
[Exclude(name="editable", kind="property")]
[Exclude(name="editableDisabledSkin", kind="style")]
[Exclude(name="editableDownSkin", kind="style")]
[Exclude(name="editableOverSkin", kind="style")]
[Exclude(name="editableUpSkin", kind="style")]
//--------------------------------------
// Events
//--------------------------------------
/**
* Dispatched when the selected directory displayed by this control
* changes for any reason.
*
* @eventType mx.events.FileEvent.DIRECTORY_CHANGE
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Event(name="directoryChange", type="mx.events.FileEvent")]
//--------------------------------------
// Styles
//--------------------------------------
/**
* Specifies the icon that indicates
* the root directories of the computer.
* There is no default icon.
* In MXML, you can use the following syntax to set this property:
* computerIcon="@Embed(source='computerIcon.jpg');"
*
* @default null
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="computerIcon", type="Class", format="EmbeddedFile", inherit="no")]
/**
* Specifies the icon that indicates a directory.
* The default icon is located in the Assets.swf file.
* In MXML, you can use the following syntax to set this property:
* directoryIcon="@Embed(source='directoryIcon.jpg');"
*
* @default TreeNodeIcon
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="directoryIcon", type="Class", format="EmbeddedFile", inherit="no")]
//--------------------------------------
// Other metadata
//--------------------------------------
[IconFile("FileSystemComboBox.png")]
[ResourceBundle("aircontrols")]
/**
* The FileSystemComboBox control defines a combo box control for
* navigating up the chain of ancestor directories from a specified
* directory in a file system.
* You often use this control with the FileSystemList and FileSystemTree
* controls to change the current directory displayed by those controls.
*
*
Unlike the standard ComboBox control, to populate the FileSystemComboBox control's
* dataProvider
property,
* you set the directory
property.
* This control then automatically sets the dataProvider
* property to an ArrayCollection of File objects
* that includes all the ancestor directories of the specified directory,
* starting with the COMPUTER
File
* and ending with the specified directory.
When you select an entry in the dropdown list,
* this control dispatches a change
event.
* After the event is dispatched data provider, and consequently the dropdown list,
* contain the selected directory's ancestors.
The <mx:FileSystemComboBox>
tag inherits all of the tag
* attributes of its superclass and adds the following tag attributes:
* <mx:FileSystemComboBox * Properties * directory="null" * indent="8" * showIcons="true" * * Styles * computerIcon="null" * directoryIcon="TreeNodeIcon" * * Events * directoryChange="No default" * /> ** * @see flash.filesystem.File * @see mx.controls.FileSystemList * @see mx.controls.FileSystemTree * * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class FileSystemComboBox extends ComboBox { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Class constants // //-------------------------------------------------------------------------- /** * A constant that can be used as a value for the
directory
property,
* representing a pseudo-top level directory named "Computer". This pseudo-directory
* contains the root directories
* (such as C:\ and D:\ on Windows or / on Macintosh).
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static const COMPUTER:File = FileSystemControlHelper.COMPUTER;
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function FileSystemComboBox()
{
super();
helper = new FileSystemControlHelper(this, false);
itemRenderer = new ClassFactory(FileSystemComboBoxRenderer);
labelFunction = helper.fileLabelFunction;
rowCount = 10;
addEventListener(Event.CHANGE, changeHandler);
directory = COMPUTER;
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
* An undocumented class that implements functionality
* shared by various file system components.
*/
mx_internal var helper:FileSystemControlHelper;
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// directory
//----------------------------------
/**
* @private
* Storage for the directory property.
*/
private var _directory:File;
/**
* @private
*/
private var directoryChanged:Boolean = false;
[Bindable("directoryChanged")]
/**
* A File object representing the directory
* whose ancestors are to be displayed in this control.
* The control displays each ancestor directory
* as a separate entry in the dropdown list.
*
* @default null
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get directory():File
{
return _directory;
}
/**
* @private
*/
public function set directory(value:File):void
{
_directory = value;
directoryChanged = true;
invalidateProperties();
dispatchEvent(new Event("directoryChanged"));
}
//----------------------------------
// indent
//----------------------------------
/**
* @private
* Storage for the indent property.
*/
private var _indent:int = 8;
/**
* The number of pixels to indent each entry in the dropdown list.
*
* @default 8
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get indent():int
{
return _indent;
}
/**
* @private
*/
public function set indent(value:int):void
{
_indent = value;
}
//----------------------------------
// showIcons
//----------------------------------
/**
* @private
* Storage for the showIcons property.
*/
private var _showIcons:Boolean = true;
/**
* A flag that determines whether icons are displayed
* before the directory names in the dropdown list.
*
* @default true
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get showIcons():Boolean
{
return _showIcons;
}
/**
* @private
*/
public function set showIcons(value:Boolean):void
{
_showIcons = value;
}
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
override protected function commitProperties():void
{
super.commitProperties();
if (directoryChanged)
{
dataProvider = getParentChain(_directory);
selectedItem = _directory;
var event:FileEvent = new FileEvent(FileEvent.DIRECTORY_CHANGE);
event.file = _directory;
dispatchEvent(event);
directoryChanged = false;
}
}
/**
* @private
*/
override protected function resourcesChanged():void
{
super.resourcesChanged();
// The name of the COMPUTER pseudo-directory is localizable.
// It appears at the top of the dropdown,
// and may also be displayed as the selected item.
invalidateSize();
invalidateDisplayList();
selectedIndex = selectedIndex;
}
/**
* @private
*/
override protected function calculatePreferredSizeFromData(count:int):Object
{
var maxW:Number = 0;
var maxH:Number = 0;
var bookmark:CursorBookmark = iterator ? iterator.bookmark : null;
iterator.seek(CursorBookmark.FIRST, 0);
var more:Boolean = iterator != null;
var lineMetrics:TextLineMetrics;
for (var i:int = 0; i < count; i++)
{
var data:Object;
if (more)
data = iterator ? iterator.current : null;
else
data = null;
var txt:String = itemToLabel(data);
lineMetrics = measureText(txt);
lineMetrics.width += i * indent;
maxW = Math.max(maxW, lineMetrics.width);
maxH = Math.max(maxH, lineMetrics.height);
if (iterator)
iterator.moveNext();
}
if (prompt)
{
lineMetrics = measureText(prompt);
maxW = Math.max(maxW, lineMetrics.width);
maxH = Math.max(maxH, lineMetrics.height);
}
maxW += getStyle("paddingLeft") + getStyle("paddingRight");
if (iterator)
iterator.seek(bookmark, 0);
return { width: maxW, height: maxH };
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* @private
* Returns an Array of File objects
* representing the path to the specified directory.
* The first File represents a root directory.
* The last File represents the specified file's parent directory.
*/
private function getParentChain(file:File):Array
{
if (helper.isComputer(file))
return [ file ];
var a:Array = [];
for (var f:File = file; f != null; f = f.parent)
{
a.unshift(f);
}
a.unshift(COMPUTER);
return a;
}
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
/**
* @private
* When the user chooses a directory along the path,
* change this control to display the path to that directory.
*/
private function changeHandler(event:Event):void
{
directory = File(selectedItem);
}
}
}