blob: 43cb40be37446e7309265496e0ec1e49a13e3590 [file] [log] [blame]
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<s:Group 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:components="com.flexcapacitor.components.*"
xmlns:c="com.flexcapacitor.controls.*"
xmlns:local="*"
width="400" height="300"
show="group1_showHandler(event)"
creationComplete="creationComplete()"
implements="com.flexcapacitor.components.IDocumentContainer"
>
<!--
WE SHOULD REFACTOR THIS
Sometimes the generated MXML document is blank. I think it's because if we open
multiple documents the application never gets completely loaded or rendered in it's tab and the
user closes the document and reopens it. I think it has to do with the activate event in Flex
So we need to wait before opening new documents until application complete on the current document.
We might need to add an event listener in the Document or Project class to make sure each application
completely loads before opening the next.
-->
<fx:Script>
<![CDATA[
import com.flexcapacitor.controller.Radiate;
import com.flexcapacitor.events.RadiateEvent;
import com.flexcapacitor.model.IDocument;
import com.flexcapacitor.utils.supportClasses.ComponentDescription;
import mx.core.IVisualElement;
import mx.core.IVisualElementContainer;
import mx.events.FlexEvent;
import mx.events.ResizeEvent;
import mx.managers.SystemManager;
import mx.utils.NameUtil;
import spark.components.Application;
import org.as3commons.lang.ArrayUtils;
/**
* STEP 1.
*
* When this is added to the display list then we
* load in a blank application.
*
* We do this so that at some point we can sandbox
* the application.
* We also do this so we can load in remote applications.
* */
private function creationComplete():void {
radiate = Radiate.getInstance();
toolLayer = toolLayerInstance;
canvasBorder = canvasBorderInstance;
canvasBackground = canvasBackgroundInstance;
canvasScroller = canvasScrollerInstance;
//radiate.setCanvas(canvasBorder, canvasBackground, canvasScroller);
systemManager.allowDomain("*");
var context:LoaderContext = new LoaderContext();
/* Specify the current application's security domain. */
context.securityDomain = SecurityDomain.currentDomain;
/* Specify a new ApplicationDomain, which loads the sub-app into a
peer ApplicationDomain. */
context.applicationDomain = new ApplicationDomain();
projectLoader.trustContent = trustContent;
projectLoader.loadForCompatibility = loadForCompatibility;
projectLoader.maintainAspectRatio = maintainAspectRatio;
projectLoader.scaleContent = scaleContent;
// if not on server context throws errors
if (Security.sandboxType == Security.REMOTE) {
//projectLoader.loaderContext = context;
projectLoader.trustContent = !trustContent;
}
projectLoader.source = url;//URL.text; // "http://yourdomain.com/SubApp3.swf";
//projectLoader.autoLoad = autoLoad;
//load();
//stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
/**
* STEP 2.
*
* SWF is Loaded now listen for Application Complete
* */
protected function project_completeHandler(event:Event):void {
//var loader:SWFLoader = event.currentTarget as SWFLoader;
/*
SecurityDomain 'http://www.radii8.com/demo2/RadiateExample.html?debug=true'
tried to access incompatible context 'http://www.flexcapacitor.com/apps/aboutyou/AboutYou.swf'
SecurityError: Error #2121: Security sandbox violation: Loader.content:
http://www.radii8.com/demo2/RadiateExample.swf/[[DYNAMIC]]/3 cannot access
http://www.flexcapacitor.com/apps/urlcodec/URLCodec.swf. This may be worked around by
calling Security.allowDomain.
*/
projectLoader.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
var loaderClassName:String = NameUtil.getUnqualifiedClassName(projectLoader.content);
if (projectLoader.content is DisplayObject) {
//parentAllowsChild.selected = b.parentAllowsChild;
//childAllowsParent.selected = b.childAllowsParent;
targetSystemManager = projectLoader.content as SystemManager;
targetSystemManager.addEventListener(FlexEvent.APPLICATION_COMPLETE, applicationComplete);
//LoaderInfo(targetApplication.loaderInfo).uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
}
hideBusyIndicators();
//Radiate.log.info("SWF Loaded");
}
/**
* STEP 3.
*
* Blank application loaded. Import the document.
* */
protected function applicationComplete(event:Event):void {
var loader:Object = event.currentTarget;
var radiate:Radiate = Radiate.instance;
//parentAllowsChild.selected = b.parentAllowsChild;
//childAllowsParent.selected = b.childAllowsParent;
targetSystemManager = loader as SystemManager;
targetApplication = loader.application;
// 8.5 x 11 at 72dpi is 612x792
targetApplication.width = Radiate.DEFAULT_DOCUMENT_WIDTH;
targetApplication.height = Radiate.DEFAULT_DOCUMENT_HEIGHT;
updateBackgroundSize();
iDocument.instance = targetApplication;
//radiate.setDocument(iDocument);
//radiate.setTarget(targetApplication);
//codeAvailable = true;
//Radiate.log.info("Document container app complete");
if (iDocument.source) {
validateNow();
iDocument.parseSource();
iDocument.resetSaveStatus();
updateBackgroundSize();
//parseDocument(codeToLoad);
//codeAvailable = false;
// we should dispatch an event when parsing is complete
}
radiate.addEventListener(RadiateEvent.SCALE_CHANGE, scaleChange, false, 0, true);
//radiate.addEventListener(RadiateEvent.DOCUMENT_SIZE_CHANGE, scaleChange, false, 0, true);
radiate.addEventListener(RadiateEvent.PROPERTY_CHANGED, propertyChange, false, 0, true);
radiate.setDocument(iDocument);
radiate.setTarget(targetApplication);
//updateAppScrollPosition();
//setTimeout(updateAppScrollPosition, 10);
//setTimeout(updateAppScrollPosition, 100);
//setTimeout(updateAppScrollPosition, 500);
hideBusyIndicators();
applicationReady = true;
radiate.centerApplication(true);
//Radiate.log.info("Application Complete");
}
/**
* The document / application
* */
public var targetApplication:Object;
/*[Embed(source="assets/460/application.swf")]
public var embeddedApplication:Class*/
private var _url:String = "application.swf";
public var autoLoad:Boolean = true;
private var radiate:Radiate;
/**
* Set to false.
* */
private var loadForCompatibility:Boolean;
/**
* Maintains the aspect ratio
* */
private var maintainAspectRatio:Boolean = true;
/**
* Set to false to prevent application from scaling to fit (vs resizing)
* */
private var scaleContent:Boolean;
/**
* Set to false for loading local file? And true for loading remote swf.
* */
private var trustContent:Boolean;
/**
* System manager of the target application
* */
private var targetSystemManager:SystemManager;
/**
* Padding to add around the document if it is too large to
* fit in the available space.
* */
public var documentPadding:int = 25;
/**
* True when updating the document and background size
* */
public var inUpdateBackgroundSize:Boolean = true;
/**
* Application ready
* */
public var applicationReady:Boolean;
/**
*
* */
public var codeAvailable:Boolean;
/**
*
* */
public var codeToLoad:String;
private var _componentDescription:ComponentDescription;
/**
* Root component description
* */
public function get componentDescription():ComponentDescription {
return _componentDescription;
}
/**
* @private
*/
[Bindable]
public function set componentDescription(value:ComponentDescription):void {
_componentDescription = value;
}
private var _documentDescription:IDocument;
public function get iDocument():IDocument {
return _documentDescription;
}
/**
* Reference to document description
* */
[Bindable]
public function set iDocument(value:IDocument):void {
if (_documentDescription == value) return;
_documentDescription = value;
//load();
}
private var _toolLayer:IVisualElementContainer;
public function get toolLayer():IVisualElementContainer {
return _toolLayer;
}
/**
* Reference to the tool layer
* */
[Bindable]
public function set toolLayer(value:IVisualElementContainer):void {
_toolLayer = value;
}
private var _canvasBorder:IVisualElementContainer;
public function get canvasBorder():IVisualElementContainer {
return _canvasBorder;
}
/**
* Canvas border
* */
[Bindable]
public function set canvasBorder(value:IVisualElementContainer):void {
_canvasBorder = value;
}
private var _canvasBackground:IVisualElementContainer;
/**
* Reference to the canvas background
* */
public function get canvasBackground():IVisualElementContainer {
return _canvasBackground;
}
public function set canvasBackground(value:IVisualElementContainer):void {
_canvasBackground = value;
}
private var _canvasScroller:Scroller;
public function get canvasScroller():Scroller {
return _canvasScroller;
}
/**
* Canvas scroller
* */
[Bindable]
public function set canvasScroller(value:Scroller):void {
_canvasScroller = value;
}
/**
*
* */
public function importDocument(code:String):Boolean {
load();
codeToLoad = code;
codeAvailable = true;
return true;
}
/**
*
* */
[Bindable]
public function get url():String {
return _url;
}
public function set url(value:String):void {
_url = value;
load();
}
/**
* Load blank Spark Application SWF
* */
public function load():void {
removeErrorMessages();
showBusyIndicators();
if (url) {
try {
//projectLoader.trustContent = trustContent;
projectLoader.loaderContext = null;
projectLoader.source = "";
projectLoader.source = url;
projectLoader.load();
}
catch (error:Error) {
Radiate.log.error(error.message);
hideBusyIndicators();
}
}
else {
hideBusyIndicators();
}
}
/**
* Load URL
* */
public function loadRemote(url:String, trustContent:Boolean = true, loadForCompatibility:Boolean = false):void {
systemManager.allowDomain("*");
showBusyIndicators();
if (url) {
try {
// if not on server context throws errors
//if (Security.sandboxType == Security.REMOTE) {
//projectLoader.loaderContext = context;
projectLoader.trustContent = trustContent;
//}
var context:LoaderContext = new LoaderContext();
/* Specify the current application's security domain. */
//context.securityDomain = SecurityDomain.currentDomain;
//projectLoader.loaderContext = context;
projectLoader.loadForCompatibility = loadForCompatibility;
projectLoader.source = "";
projectLoader.source = url;
projectLoader.load();
}
catch (error:Error) {
Radiate.log.error(error.message);
hideBusyIndicators();
}
}
else {
hideBusyIndicators();
}
}
protected function allowDomainHandler(event:MouseEvent):void {
systemManager.allowDomain("*");
}
private function uncaughtErrorHandler(event:UncaughtErrorEvent):void {
event.preventDefault();
//to capture the error message
var errorMessage:String = new String();
if (event.error is Error) {
errorMessage = Error( event.error ).message;
}
else if (event.error is ErrorEvent) {
errorMessage = ErrorEvent( event.error ).text;
}
else {
errorMessage = event.error.toString();
}
//Radiate.logTarget.logEvent(new LogEvent("Uncaught Error", LogEventLevel.ERROR));
Radiate.log.error(errorMessage);
//trace("Uncaught error", event);
hideBusyIndicators();
}
/**
*
* */
protected function project_ioErrorHandler(event:IOErrorEvent):void {
//trace("ioerror");
Radiate.log.error(event.text);
hideBusyIndicators();
}
/**
*
* */
protected function project_securityErrorHandler(event:SecurityErrorEvent):void
{
//trace("security error");
Radiate.log.error(event.text);
hideBusyIndicators();
}
/**
*
* */
protected function project_initHandler(event:Event):void
{
//trace("init");
}
/**
*
* */
protected function project_progressHandler(event:ProgressEvent):void
{
//trace("PROGRESS");
}
/**
*
* */
protected function project_unloadHandler(event:Event):void
{
//trace("unload");
Radiate.log.info("SWF unloaded");
hideBusyIndicators();
}
/**
*
* */
protected function project_openHandler(event:Event):void
{
//trace("open");
showBusyIndicators();
}
/**
*
* */
protected function project_httpStatusHandler(event:HTTPStatusEvent):void {
//trace("http status");
}
/**
* Show busy indicatos
* */
public function showBusyIndicators():void {
//fadeOutBusy.end();
//fadeInBusy.play();
if (!loadingLabel || !toolLayer || !canvasBorder) return;
loadingLabel.visible = true;
IVisualElement(toolLayer).visible = false;
canvasBorderInstance.visible = false;
}
/**
* Hide busy indicators
* */
public function hideBusyIndicators():void {
if (!loadingLabel || !toolLayer || !canvasBorder) return;
loadingLabel.visible = false;
toolLayerInstance.visible = true;
canvasBorderInstance.visible = true;
}
/**
* Make sure we are showing the correct document
* */
protected function group1_showHandler(event:FlexEvent):void {
if (radiate.selectedDocument!=iDocument) {
radiate.setDocument(radiate.selectedDocument, true);// maybe call update document here???
}
Radiate.log.info("Document SHOW event");
}
/**
* Reload blank app
* */
public function reload():void {
creationComplete();
}
/**
*
* */
private function removeErrorMessages():void {
if (projectLoader && projectLoader.loaderInfo) {
projectLoader.loaderInfo.uncaughtErrorEvents.removeEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
}
if (targetSystemManager) {
//parentAllowsChild.selected = b.parentAllowsChild;
//childAllowsParent.selected = b.childAllowsParent;
targetSystemManager.removeEventListener(FlexEvent.APPLICATION_COMPLETE, applicationComplete);
}
}
/**
*
* */
private function canvasBorder_resizeHandler(event:ResizeEvent):void {
if (targetApplication) {
updateBackgroundSize();
}
}
/**
* Update the size of the target application
* */
private function updateAppScrollPosition():void {
if (targetApplication is DisplayObject) {
radiate.centerApplication();
}
}
/**
* Handles the clipping, scaling and sizing of the target application.
* Could be moved to update display list???
* */
public function updateBackgroundSize():void {
//if (inUpdateBackgroundSize) return;
inUpdateBackgroundSize = true;
// size canvas background to be the minimum size of the scroller
// or the size of the target application + 50
var scaledDocumentWidth:int = targetApplication.width * targetApplication.scaleX;
var scaledDocumentHeight:int = targetApplication.height * targetApplication.scaleY;
/*var aspectRatio:String = scaledDocumentWidth/scaledDocumentHeight>1?"portrait":"landscape";
if (aspectRatio!=canvasBorder.skin.currentState) {
canvasBorder.skin.currentState = aspectRatio;
}*/
var scaledPaddedDocumentWidth:int = documentPadding + (targetApplication.width * targetApplication.scaleX);
var scaledPaddedDocumentHeight:int = documentPadding + (targetApplication.height * targetApplication.scaleY);
var scrollerWidth:int = canvasScroller.width;
var scrollerHeight:int = canvasScroller.height;
var scrollerPaddedWidth:int = canvasScroller.width + documentPadding;
var scrollerPaddedHeight:int = canvasScroller.height + documentPadding;
var visiblePaddedWidth:int = canvasScroller.width - documentPadding;
var visiblePaddedHeight:int = canvasScroller.height - documentPadding;
var minimumWidth:int;
var minimumHeight:int;
// if content width is more than available width plus padding then
// set minimum width to show scrollbars and add padding
if (scaledPaddedDocumentWidth >= visiblePaddedWidth+10) {
minimumWidth = Math.max(scrollerWidth, scaledPaddedDocumentWidth);
}
else {
minimumWidth = scrollerWidth;
}
// if content height is more than available height plus padding then
// set minimum height to show scrollbars and add padding
if (scaledPaddedDocumentHeight >=visiblePaddedHeight+10) {
minimumHeight = Math.max(scrollerPaddedHeight, scaledPaddedDocumentHeight);
}
else {
minimumHeight = scrollerHeight;
}
canvasBackgroundParent.percentWidth = 100;
canvasBackgroundParent.percentHeight = 100;
canvasBackgroundInstance.width = minimumWidth;//Math.max(canvasScroller.width, minimumWidth);
canvasBackgroundInstance.height = minimumHeight;//Math.max(canvasScroller.height, minimumHeight);
canvasBorderInstance.width = scaledDocumentWidth;
canvasBorderInstance.height = scaledDocumentHeight;
projectLoader.width = scaledDocumentWidth;
projectLoader.height = scaledDocumentHeight;
// we do this because when we scale the application the
// system manager mask is not updated and the content gets clipped
targetSystemManager.setActualSize(scaledDocumentWidth, scaledDocumentHeight);
validateNow();
inUpdateBackgroundSize = false;
}
/**
* Update the position of the document
* */
protected function scaleChange(event:RadiateEvent):void {
//if (!inUpdateBackgroundSize) {
updateBackgroundSize();
//}
}
public var importantProperties:Array = ["width", "explicitWidth", "height", "explicitHeight","scaleX","scaleY"];
/**
* Update the size of the document
* */
protected function propertyChange(event:RadiateEvent):void {
var sizeChange:Boolean;
if (event.selectedItem is Application) {
sizeChange = ArrayUtils.containsAny(event.properties, importantProperties);
if (sizeChange) {
updateBackgroundSize();
}
}
}
protected function canvasBackground_resizeHandler(event:ResizeEvent):void {
}
protected function canvasBackgroundParent_resizeHandler(event:ResizeEvent):void {
}
protected function projectLoader_resizeHandler(event:ResizeEvent):void {
//Radiate.log.info("Project loader resize");
}
/**
*
* */
private function updateScrollBarPosition(center:Point=null):void {
/*if (canvasBackground.contentHeight > canvasBackground.height) {
//canvasBackground.verticalScrollPosition = int((canvasBackground.contentHeight-canvasBackground.height)/2)
}
else {
//canvasBackground.verticalScrollPosition = 0;
}*/
/*if (borderContainer.contentHeight > borderContainer.height) {
borderContainer.verticalScrollPosition = int((borderContainer.contentHeight-borderContainer.height)/2);
}
else {
borderContainer.verticalScrollPosition = 0;
}
if (borderContainer.contentWidth > borderContainer.width) {
borderContainer.horizontalScrollPosition = int((borderContainer.contentWidth-borderContainer.width)/2);
}
else {
borderContainer.horizontalScrollPosition = 0;
}*/
}
/**
* Not used but probably should be
* */
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
return;
}
private var _showBorders:Boolean;
/**
*
* */
public function get showBorders():Boolean {
return _showBorders;
}
/**
* Show borders for debugging layout of application
* */
public function set showBorders(value:Boolean):void {
if (_showBorders == value) return;
_showBorders = value;
if (_showBorders) {
canvasBackgroundParent.setStyle("backgroundColor", 0xF00000);
canvasBackgroundInstance.setStyle("backgroundColor", 0xFF0000);
canvasBorderInstance.setStyle("backgroundColor", 0xFFF000);
toolLayerInstance.setStyle("backgroundColor", 0xFFFF00);
canvasBackgroundParent.setStyle("backgroundAlpha", 1);
canvasBackgroundInstance.setStyle("backgroundAlpha", 1);
canvasBorderInstance.setStyle("backgroundAlpha", 1);
toolLayerInstance.setStyle("backgroundAlpha", 1);
}
else {
canvasBackgroundParent.setStyle("backgroundAlpha", 0);
canvasBackgroundInstance.setStyle("backgroundAlpha", 0);
canvasBorderInstance.setStyle("backgroundAlpha", 0);
toolLayerInstance.setStyle("backgroundAlpha", 0);
}
}
/**
*
* */
protected function scrollerCornerButton_clickHandler(event:MouseEvent):void {
//showBorders = !showBorders;
//if (!inUpdateBackgroundSize) {
radiate.centerApplication();
//}
}
/**
*
* */
protected function scroller_resizeHandler(event:ResizeEvent):void {
if (!targetApplication) return;
//if (!inUpdateBackgroundSize) {
updateBackgroundSize();
//}
}
protected function canvasScrollerInstance_creationCompleteHandler(event:FlexEvent):void {
var enableMouseSupport:Boolean = false;
if (enableMouseSupport) {
canvasScrollerInstance.addEventListener(MouseEvent.MOUSE_WHEEL, list_mouseWheel, true);
}
}
protected function list_mouseWheel(e:MouseEvent):void {
e.preventDefault();
e.stopImmediatePropagation();
canvasScrollerInstance.viewport.verticalScrollPosition -= e.delta * 5;
}
protected function drawGrid(sprite:Sprite):void {
var x:int = 0;
var y:int = 0;
sprite.graphics.clear();
// draw the background
sprite.graphics.beginFill(0xFFFFFF);
sprite.graphics.drawRect(0, 0, sprite.width, sprite.height);
sprite.graphics.endFill();
sprite.graphics.lineStyle(0.5, 0x000000, 0.2);
// draw the vertical lines
while (x <= sprite.width) {
sprite.graphics.moveTo(x, 0);
sprite.graphics.lineTo(x, sprite.height);
x = x + 20;
}
// draw the horizontal lines
while (y <= sprite.height) {
sprite.graphics.moveTo(0, y);
sprite.graphics.lineTo(sprite.width, y);
y = y + 20;
}
}
]]>
</fx:Script>
<fx:Declarations>
<!--<s:Fade id="fadeInBusy"
alphaTo="1"
target="{busyIndicator}"
effectStart="busyIndicator.visible=true"
effectEnd="busyIndicator.visible=true"/>
<s:Fade id="fadeOutBusy"
alphaTo="0"
target="{busyIndicator}"
effectStart="busyIndicator.visible=true"
effectEnd="busyIndicator.visible=false"/>-->
<fx:XML id="testModel" xmlns="">
<mx:MXML >
<s:Group x="15" y="50">
<s:Button label="Hello World" x="20" y="20" color="#ff0000"/>
</s:Group >
</mx:MXML>
</fx:XML>
</fx:Declarations>
<s:Rect id="backgroundRect" width="100%" height="100%">
<s:fill>
<s:SolidColor color="#666666"/>
</s:fill>
</s:Rect>
<s:Rect width="20" height="20">
<s:fill>
<s:SolidColor color="#FFFFFF"/>
</s:fill>
</s:Rect>
<s:Scroller id="canvasScrollerInstance"
left="20"
right="0"
top="20"
bottom="0"
width="100%"
height="100%"
resize="scroller_resizeHandler(event)"
interactionMode="mouse"
creationComplete="canvasScrollerInstance_creationCompleteHandler(event)"
>
<!--- why two containers around this? reasons below -->
<!--
// clicked on background area
if (target==canvasBackground || target==canvasBackgroundParent) {
radiate.setTarget(targetApplication, true);
-->
<!---
This first group is sized by the Scroller.
The scroller automatically sets this group, the viewport, to 100%
-->
<s:Group id="canvasBackgroundParent"
width="100%"
height="100%" >
<!---
This second group is to provide padding to the top and bottom of the document
and to receive any mouse events such as zoom in and out.
It gets sized to the canvas size plus the padding value.
It may also be used for skinning with different devices.
-->
<s:BorderContainer id="canvasBackgroundInstance"
borderVisible="false"
backgroundAlpha="0"
>
<!---
This third group is to mask application content.
Without it the application or the application's system manager
may bleed over.
-->
<s:BorderContainer id="canvasBorderInstance"
verticalCenter="0"
horizontalCenter="0"
backgroundAlpha="0"
borderVisible="false"
visible="false"
resize="canvasBorder_resizeHandler(event)">
<!--<s:SkinnableContainer id="canvasBorder"
verticalCenter="0"
horizontalCenter="0"
visible="false"
backgroundAlpha="1"
skinClass="com.flexcapacitor.skins.DeviceSkin"
>-->
<!---
This group contains the system manager and the blank application
-->
<s:SWFLoader id="projectLoader"
resize="projectLoader_resizeHandler(event)"
complete="project_completeHandler(event)"
httpStatus="project_httpStatusHandler(event)"
init="project_initHandler(event)"
ioError="project_ioErrorHandler(event)"
open="project_openHandler(event)"
progress="project_progressHandler(event)"
securityError="project_securityErrorHandler(event)"
unload="project_unloadHandler(event)"/>
<!---
This group is used to add visual elements above the application.
For example, selection and resizing borders.
-->
<s:Group id="toolLayerInstance"
mouseChildren="false"
mouseEnabled="false">
</s:Group>
</s:BorderContainer>
<!--</s:SkinnableContainer>-->
</s:BorderContainer>
</s:Group>
</s:Scroller>
<s:Label id="loadingLabel" color="#ffffff" text="Loading. Please wait..."
fontWeight="bold" horizontalCenter="0" verticalCenter="0"/>
<s:Group id="scrollerCornerButton"
width="16" height="16" right="0" bottom="0"
click="scrollerCornerButton_clickHandler(event)">
<s:Rect width="100%"
height="100%"
alpha="0"
visible="{canvasScroller.verticalScrollBar.visible &amp;&amp; canvasScroller.horizontalScrollBar.visible}"
>
<s:fill>
<s:SolidColor color="#000000"/>
</s:fill>
</s:Rect>
</s:Group>
<!-- alternatives to ruler component -->
<s:Rect left="20" width="100%" height="20">
<s:fill>
<s:SolidColor color="#FFFFFF"/>
</s:fill>
</s:Rect>
<s:Rect top="20" width="20" height="100%">
<s:fill>
<s:SolidColor color="#FFFFFF"/>
</s:fill>
</s:Rect>
<!--<components:Ruler left="20" width="100%" height="20"/>
<components:Ruler top="20" width="20" height="100%" direction="vertical"/>-->
<!--<s:BusyIndicator id="busyIndicator" right="20" top="10" symbolColor="white"/>-->
</s:Group>