http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/controller/Radiate.as ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/controller/Radiate.as b/Radii8Library/src/com/flexcapacitor/controller/Radiate.as new file mode 100644 index 0000000..a795b4c --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/controller/Radiate.as @@ -0,0 +1,8868 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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 com.flexcapacitor.controller { + import com.flexcapacitor.components.DocumentContainer; + import com.flexcapacitor.components.IDocumentContainer; + import com.flexcapacitor.effects.core.CallMethod; + import com.flexcapacitor.events.HistoryEvent; + import com.flexcapacitor.events.HistoryEventItem; + import com.flexcapacitor.events.RadiateEvent; + import com.flexcapacitor.logging.RadiateLogTarget; + import com.flexcapacitor.model.AttachmentData; + import com.flexcapacitor.model.Device; + import com.flexcapacitor.model.Document; + import com.flexcapacitor.model.DocumentData; + import com.flexcapacitor.model.EventMetaData; + import com.flexcapacitor.model.IDocument; + import com.flexcapacitor.model.IDocumentData; + import com.flexcapacitor.model.IDocumentMetaData; + import com.flexcapacitor.model.IProject; + import com.flexcapacitor.model.IProjectData; + import com.flexcapacitor.model.ISavable; + import com.flexcapacitor.model.ImageData; + import com.flexcapacitor.model.InspectableClass; + import com.flexcapacitor.model.InspectorData; + import com.flexcapacitor.model.MetaData; + import com.flexcapacitor.model.Project; + import com.flexcapacitor.model.SaveResultsEvent; + import com.flexcapacitor.model.SavedData; + import com.flexcapacitor.model.Settings; + import com.flexcapacitor.model.StyleMetaData; + import com.flexcapacitor.services.IServiceEvent; + import com.flexcapacitor.services.WPAttachmentService; + import com.flexcapacitor.services.WPService; + import com.flexcapacitor.services.WPServiceEvent; + import com.flexcapacitor.tools.ITool; + import com.flexcapacitor.utils.ClassUtils; + import com.flexcapacitor.utils.DisplayObjectUtils; + import com.flexcapacitor.utils.SharedObjectUtils; + import com.flexcapacitor.utils.TypeUtils; + import com.flexcapacitor.utils.XMLUtils; + import com.flexcapacitor.utils.supportClasses.ComponentDefinition; + import com.flexcapacitor.utils.supportClasses.ComponentDescription; + import com.flexcapacitor.views.IInspector; + import com.google.code.flexiframe.IFrame; + + import flash.desktop.Clipboard; + import flash.display.Bitmap; + import flash.display.BitmapData; + import flash.display.DisplayObject; + import flash.display.IBitmapDrawable; + import flash.events.ErrorEvent; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.IEventDispatcher; + import flash.events.IOErrorEvent; + import flash.events.SecurityErrorEvent; + import flash.external.ExternalInterface; + import flash.geom.Point; + import flash.globalization.DateTimeStyle; + import flash.net.FileReference; + import flash.net.SharedObject; + import flash.system.ApplicationDomain; + import flash.ui.Mouse; + import flash.ui.MouseCursorData; + import flash.utils.ByteArray; + import flash.utils.Dictionary; + import flash.utils.getTimer; + + import mx.collections.ArrayCollection; + import mx.containers.Grid; + import mx.containers.GridItem; + import mx.containers.GridRow; + import mx.containers.TabNavigator; + import mx.controls.LinkButton; + import mx.core.ClassFactory; + import mx.core.DeferredInstanceFromFunction; + import mx.core.IUIComponent; + import mx.core.IVisualElement; + import mx.core.IVisualElementContainer; + import mx.core.UIComponent; + import mx.core.mx_internal; + import mx.effects.effectClasses.PropertyChanges; + import mx.graphics.ImageSnapshot; + import mx.graphics.SolidColor; + import mx.logging.AbstractTarget; + import mx.logging.ILogger; + import mx.logging.Log; + import mx.logging.LogEventLevel; + import mx.managers.ILayoutManager; + import mx.managers.LayoutManager; + import mx.printing.FlexPrintJob; + import mx.printing.FlexPrintJobScaleType; + import mx.states.AddItems; + import mx.styles.IStyleClient; + import mx.utils.ArrayUtil; + import mx.utils.ObjectUtil; + + import spark.components.Application; + import spark.components.BorderContainer; + import spark.components.Button; + import spark.components.ComboBox; + import spark.components.Grid; + import spark.components.Image; + import spark.components.Label; + import spark.components.NavigatorContent; + import spark.components.Scroller; + import spark.components.SkinnableContainer; + import spark.components.supportClasses.GroupBase; + import spark.components.supportClasses.SkinnableTextBase; + import spark.components.supportClasses.TextBase; + import spark.core.ContentCache; + import spark.core.IViewport; + import spark.effects.SetAction; + import spark.formatters.DateTimeFormatter; + import spark.layouts.BasicLayout; + import spark.primitives.BitmapImage; + import spark.primitives.Rect; + import spark.skins.spark.DefaultGridItemRenderer; + + import org.as3commons.lang.ArrayUtils; + import org.as3commons.lang.DictionaryUtils; + import org.as3commons.lang.ObjectUtils; + + use namespace mx_internal; + + /** + * Dispatched when register results are received + * */ + [Event(name="registerResults", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when a print job is cancelled + * */ + [Event(name="printCancelled", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when an item is added to the target + * */ + [Event(name="addItem", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when an item is removed from the target + * */ + [Event(name="removeItem", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when an item is removed from the target + * */ + [Event(name="removeTarget", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when the target is changed + * */ + [Event(name="targetChange", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when the document is changed + * */ + [Event(name="documentChange", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when a document is opening + * */ + [Event(name="documentOpening", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when a document is opened + * */ + [Event(name="documentOpen", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when a document is renamed + * */ + [Event(name="documentRename", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when the project is changed + * */ + [Event(name="projectChange", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when the project is deleted + * */ + [Event(name="projectDeletedResults", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when the project is created + * */ + [Event(name="projectCreated", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when a property on the target is changed. + * Using propertyChanged instead of propertyChange because of error with bindable + * tag using propertyChange: + * TypeError: Error #1034: Type Coercion failed: cannot convert mx.events::PropertyChangeEvent@11d2187b1 to com.flexcapacitor.events.RadiateEvent. + * */ + [Event(name="propertyChanged", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when a property is selected on the target + * */ + [Event(name="propertySelected", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when a property edit is requested + * */ + [Event(name="propertyEdit", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when the tool changes + * */ + [Event(name="toolChange", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when the scale changes + * */ + [Event(name="scaleChange", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when the document size or scale changes + * */ + [Event(name="documentSizeChange", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Not used yet. + * */ + [Event(name="initialized", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Used when the tools list has been updated. + * */ + [Event(name="toolsUpdated", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Used when the components list is updated. + * */ + [Event(name="componentsUpdated", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Used when the document canvas is updated. + * */ + [Event(name="canvasChange", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Event to request a preview if available. Used for HTML preview. + * */ + [Event(name="requestPreview", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when the generated code is updated. + * */ + [Event(name="codeUpdated", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when a color is selected. + * */ + [Event(name="colorSelected", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Dispatched when an object is selected + * */ + [Event(name="objectSelected", type="com.flexcapacitor.radiate.events.RadiateEvent")] + + /** + * Main class and API that handles the interactions between the view and the models. + * + * Dispatches events and exposes methods to manipulate the documents. + * + * It contains a list of components, tools, devices, inspectors (panels), assets and + * in the future we should add skins, effects and so on. + * These items are created from an XML file at startup so we can configure what is available + * to our user or project. We do this so we can also load in a remote SWF to add + * additional components, sounds, images, skins, inspectors, fonts, etc + * + * Currently we are saving and loading to a remote location or to a local shared object. + * To save to a local file system we will need to modify these functions. + * + * This class supports an Undo / Redo history. The architecture is loosely based on + * the structure found in the Effects classes. We may want to be a proxy to the documents + * and call undo and redo on them since we would like to support more than one + * type of document. + * + * This class can be broken up into multiple classes since it is also handling + * saving and loading and services. + * + * To set a property or style call setProperty or setStyle. + * To add a component call addElement. + * To log a message to the console call Radiate.log.info() or error(). + * + * To undo call undo + * To redo call redo + * + * To get the history index access history index + * To check if history exists call the has history + * To check if undo can be performed access has undo + * To check if redo can be performed access has redo + * + * Editing through cut, copy and paste is only partially implemented. + * */ + public class Radiate extends EventDispatcher { + + public static const SAME_OWNER:String = "sameOwner"; + public static const SAME_PARENT:String = "sameParent"; + public static const ADDED:String = "added"; + public static const MOVED:String = "moved"; + public static const REMOVED:String = "removed"; + public static const ADD_ERROR:String = "addError"; + public static const REMOVE_ERROR:String = "removeError"; + public static const RADIATE_LOG:String = "radiate"; + public static const LOGGED_IN:String = "loggedIn"; + public static const LOGGED_OUT:String = "loggedOut"; + + public function Radiate(s:SINGLEDOUBLE) { + super(target as IEventDispatcher); + + // Create a target + setLoggingTarget(defaultLogTarget); + + + // initialize - maybe call on startup() instead + initialize(); + } + + //---------------------------------- + // instance + //---------------------------------- + private static var _instance:Radiate; + + /** + * Attempt to support a console part 2 + * */ + public static function get log():ILogger { + + if (_log) { + return _log; + } + else { + setLoggingTarget(defaultLogTarget); + return _log; + } + } + + /** + * @private + */ + public static function set log(value:ILogger):void { + _log = value; + } + + /** + * Attempt to support a console part 3 + * */ + public static function get console():Object { + return _console; + } + + /** + * @private + */ + public static function set console(value:Object):void { + _console = value; + + if ("console" in logTarget) { + logTarget["console"] = value; + } + } + + public static function get instance():Radiate + { + if (!_instance) { + _instance = new Radiate(new SINGLEDOUBLE()); + } + return _instance; + } + + public static function getInstance():Radiate { + return instance; + } + + /** + * Create references for classes we need. + * */ + public static var radiateReferences:RadiateReferences; + + /** + * If true then importing document + * */ + public static var importingDocument:Boolean; + + /** + * Upload attachment + * */ + public var uploadAttachmentService:WPAttachmentService; + + /** + * Service to get list of attachments + * */ + public var getAttachmentsService:WPService; + + /** + * Service to get list of projects + * */ + public var getProjectsService:WPService; + + /** + * Service to delete attachment + * */ + public var deleteAttachmentService:WPService; + + /** + * Service to delete document + * */ + public var deleteDocumentService:WPService; + + /** + * Service to delete project + * */ + public var deleteProjectService:WPService; + + /** + * Service to request reset the password + * */ + public var lostPasswordService:WPService; + + /** + * Service to change the password + * */ + public var changePasswordService:WPService; + + /** + * Service to login + * */ + public var loginService:WPService; + + /** + * Service to logout + * */ + public var logoutService:WPService; + + /** + * Service to register + * */ + public var registerService:WPService; + + /** + * Service to check if user is logged in + * */ + public var getLoggedInStatusService:WPService; + + /** + * Set to true when a document is being saved to the server + * */ + [Bindable] + public var saveDocumentInProgress:Boolean; + + /** + * Set to true when project is being saved to the server + * */ + [Bindable] + public var saveProjectInProgress:Boolean; + + /** + * Set to true when checking if user is logged in + * */ + [Bindable] + public var getLoggedInStatusInProgress:Boolean; + + /** + * Set to true when lost password call is made + * */ + [Bindable] + public var lostPasswordInProgress:Boolean; + + /** + * Set to true when changing password + * */ + [Bindable] + public var changePasswordInProgress:Boolean; + + /** + * Set to true when registering + * */ + [Bindable] + public var registerInProgress:Boolean; + + /** + * Set to true when logging in + * */ + [Bindable] + public var loginInProgress:Boolean; + + /** + * Set to true when logging out + * */ + [Bindable] + public var logoutInProgress:Boolean; + + /** + * Set to true when deleting a project + * */ + [Bindable] + public var deleteProjectInProgress:Boolean; + + /** + * Set to true when deleting a document + * */ + [Bindable] + public var deleteDocumentInProgress:Boolean; + + /** + * Set to true when deleting an attachment + * */ + [Bindable] + public var deleteAttachmentInProgress:Boolean; + + /** + * Set to true when getting list of attachments + * */ + [Bindable] + public var getAttachmentsInProgress:Boolean; + + /** + * Set to true when uploading an attachment + * */ + [Bindable] + public var uploadAttachmentInProgress:Boolean; + + /** + * Set to true when getting list of projects + * */ + [Bindable] + public var getProjectsInProgress:Boolean; + + /** + * Is user logged in + * */ + [Bindable] + public var isUserLoggedIn:Boolean; + + /** + * Default storage location for save and load. + * */ + [Bindable] + public var defaultStorageLocation:String; + + /** + * Can user connect to the service + * */ + [Bindable] + public var isUserConnected:Boolean; + + /** + * Avatar of user + * */ + [Bindable] + public var userAvatar:String = "assets/images/icons/gravatar.png"; + + /** + * Path to default avatar of user (from Gravatar) + * Gravatars icons don't work locally so using path. + * Default - http://0.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=96 + * local - assets/images/icons/gravatar.png + * */ + [Bindable] + public var defaultUserAvatarPath:String = "assets/images/icons/gravatar.png"; + + /** + * User info + * */ + [Bindable] + public var user:Object; + + /** + * User email + * */ + [Bindable] + public var userEmail:String; + + /** + * User id + * */ + [Bindable] + public var userID:int = -1; + + /** + * User sites + * */ + [Bindable] + public var userSites:Array = []; + + /** + * User site path + * */ + [Bindable] + public var userSitePath:String; + + /** + * User display name + * */ + [Bindable] + public var userDisplayName:String = "guest"; + + /** + * Last save date + * */ + [Bindable] + public var lastSaveDate:String; + + /** + * Cut data + * */ + public var cutData:Object; + + /** + * Cut data + * */ + public var copiedData:Object; + + /** + * Auto save locations + * */ + [Bindable] + public var autoSaveLocations:String; + + private var _enableAutoSave:Boolean; + + [Bindable] + /** + * Auto save enabled + * */ + public function get enableAutoSave():Boolean { + return _enableAutoSave; + } + + /** + * @private + */ + public function set enableAutoSave(value:Boolean):void { + _enableAutoSave = value; + + + if (value) { + if (!autoSaveEffect) { + autoSaveEffect = new CallMethod(); + autoSaveEffect.method = autoSaveHandler; + autoSaveEffect.repeatCount = 0; + autoSaveEffect.repeatDelay = autoSaveInterval; + } + if (!autoSaveEffect.isPlaying) { + autoSaveEffect.play(); + } + } + else { + autoSaveEffect.stop(); + } + } + + /** + * Interval to check to save project + * */ + public var autoSaveInterval:int = 30000; + + /** + * Effect to auto save + * */ + public var autoSaveEffect:CallMethod; + + /** + * Handle auto saving + * */ + public function autoSaveHandler():void { + var length:int; + var iProject:IProject; + var iDocumentData:IDocumentData; + var iAttachmentData:AttachmentData; + var imageData:ImageData; + var i:int; + + // save documents + /*length = documents.length; + for (i=0;i<length;i++) { + iDocumentData = documents[i] as IDocumentData; + if (iDocumentData.isChanged && !iDocumentData.saveInProgress && iDocumentData.isOpen) { + iDocumentData.save(); + } + }*/ + + // save projects + length = projects.length; + for (i=0;i<length;i++) { + iDocumentData = projects[i] as IDocumentData; + //if (iDocumentData.isChanged && !iDocumentData.saveInProgress && iDocumentData.isOpen) { + if (!iDocumentData.saveInProgress && iDocumentData.isOpen) { + iDocumentData.save(); + } + } + + // save attachments + length = assets.length; + for (i=0;i<length;i++) { + iAttachmentData = assets[i] as ImageData; + if (iAttachmentData) { + imageData = iAttachmentData as ImageData; + + if (!imageData.saveInProgress && imageData.id==null) { + //imageData.save(); + uploadAttachment(imageData.byteArray, selectedProject.id, imageData.name, null, imageData.contentType); + } + } + } + } + + /** + * Build number + * */ + [Bindable] + public var buildNumber:String; + + /** + * Build date + * */ + [Bindable] + public var buildDate:String; + + /** + * Build time + * */ + [Bindable] + public var buildTime:String; + + //---------------------------------- + // + // Events Management + // + //---------------------------------- + + /** + * Dispatch attachments received event + * */ + public function dispatchGetProjectsListResultsEvent(data:Object):void { + var projectsListResultEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECTS_LIST_RECEIVED); + + if (hasEventListener(RadiateEvent.PROJECTS_LIST_RECEIVED)) { + projectsListResultEvent.data = data; + dispatchEvent(projectsListResultEvent); + } + } + + /** + * Dispatch print cancelled event + * */ + public function dispatchPrintCancelledEvent(data:Object, printJob:FlexPrintJob):void { + var printCancelledEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PRINT_CANCELLED); + + if (hasEventListener(RadiateEvent.PRINT_CANCELLED)) { + printCancelledEvent.data = data; + printCancelledEvent.selectedItem = printJob; + dispatchEvent(printCancelledEvent); + } + } + + /** + * Dispatch print complete event + * */ + public function dispatchPrintCompleteEvent(data:Object, printJob:FlexPrintJob):void { + var printCompleteEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PRINT_COMPLETE); + + if (hasEventListener(RadiateEvent.PRINT_COMPLETE)) { + printCompleteEvent.data = data; + printCompleteEvent.selectedItem = printJob; + dispatchEvent(printCompleteEvent); + } + } + + /** + * Dispatch attachments received event + * */ + public function dispatchLoginStatusEvent(loggedIn:Boolean, data:Object):void { + var loggedInStatusEvent:RadiateEvent = new RadiateEvent(RadiateEvent.LOGGED_IN_STATUS); + + if (hasEventListener(RadiateEvent.LOGGED_IN_STATUS)) { + loggedInStatusEvent.status = loggedIn ? LOGGED_IN : LOGGED_OUT; + loggedInStatusEvent.data = data; + dispatchEvent(loggedInStatusEvent); + } + } + + /** + * Dispatch attachments received event + * */ + public function dispatchAttachmentsResultsEvent(successful:Boolean, attachments:Array):void { + var attachmentsReceivedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.ATTACHMENTS_RECEIVED, false, false, attachments); + + if (hasEventListener(RadiateEvent.ATTACHMENTS_RECEIVED)) { + attachmentsReceivedEvent.successful = successful; + attachmentsReceivedEvent.status = successful ? "ok" : "fault"; + attachmentsReceivedEvent.targets = ArrayUtil.toArray(attachments); + dispatchEvent(attachmentsReceivedEvent); + } + } + + /** + * Dispatch upload attachment received event + * */ + public function dispatchUploadAttachmentResultsEvent(successful:Boolean, attachments:Array, data:Object):void { + var uploadAttachmentEvent:RadiateEvent = new RadiateEvent(RadiateEvent.ATTACHMENT_UPLOADED, false, false); + + if (hasEventListener(RadiateEvent.ATTACHMENT_UPLOADED)) { + uploadAttachmentEvent.successful = successful; + uploadAttachmentEvent.status = successful ? "ok" : "fault"; + uploadAttachmentEvent.data = attachments; + uploadAttachmentEvent.selectedItem = data; + dispatchEvent(uploadAttachmentEvent); + } + } + + /** + * Dispatch login results event + * */ + public function dispatchLoginResultsEvent(successful:Boolean, data:Object):void { + var loginResultsEvent:RadiateEvent = new RadiateEvent(RadiateEvent.LOGIN_RESULTS); + + if (hasEventListener(RadiateEvent.LOGIN_RESULTS)) { + loginResultsEvent.data = data; + loginResultsEvent.successful = successful; + dispatchEvent(loginResultsEvent); + } + } + + /** + * Dispatch logout results event + * */ + public function dispatchLogoutResultsEvent(successful:Boolean, data:Object):void { + var logoutResultsEvent:RadiateEvent = new RadiateEvent(RadiateEvent.LOGOUT_RESULTS); + + if (hasEventListener(RadiateEvent.LOGOUT_RESULTS)) { + logoutResultsEvent.data = data; + logoutResultsEvent.successful = successful; + dispatchEvent(logoutResultsEvent); + } + } + + /** + * Dispatch register results event + * */ + public function dispatchRegisterResultsEvent(successful:Boolean, data:Object):void { + var registerResultsEvent:RadiateEvent = new RadiateEvent(RadiateEvent.REGISTER_RESULTS); + + if (hasEventListener(RadiateEvent.REGISTER_RESULTS)) { + registerResultsEvent.data = data; + registerResultsEvent.successful = successful; + dispatchEvent(registerResultsEvent); + } + } + + /** + * Dispatch change password results event + * */ + public function dispatchChangePasswordResultsEvent(successful:Boolean, data:Object):void { + var changePasswordResultsEvent:RadiateEvent = new RadiateEvent(RadiateEvent.CHANGE_PASSWORD_RESULTS); + + if (hasEventListener(RadiateEvent.CHANGE_PASSWORD_RESULTS)) { + changePasswordResultsEvent.data = data; + changePasswordResultsEvent.successful = successful; + dispatchEvent(changePasswordResultsEvent); + } + } + + /** + * Dispatch lost password results event + * */ + public function dispatchLostPasswordResultsEvent(successful:Boolean, data:Object):void { + var lostPasswordResultsEvent:RadiateEvent = new RadiateEvent(RadiateEvent.LOST_PASSWORD_RESULTS); + + if (hasEventListener(RadiateEvent.LOST_PASSWORD_RESULTS)) { + lostPasswordResultsEvent.data = data; + lostPasswordResultsEvent.successful = successful; + dispatchEvent(lostPasswordResultsEvent); + } + } + + /** + * Dispatch project deleted results event + * */ + public function dispatchProjectDeletedEvent(successful:Boolean, data:Object):void { + var deleteProjectResultsEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECT_DELETED); + + if (hasEventListener(RadiateEvent.PROJECT_DELETED)) { + deleteProjectResultsEvent.data = data; + deleteProjectResultsEvent.successful = successful; + deleteProjectResultsEvent.status = successful ? "ok" : "error"; + dispatchEvent(deleteProjectResultsEvent); + } + } + + /** + * Dispatch document deleted results event + * */ + public function dispatchDocumentDeletedEvent(successful:Boolean, data:Object):void { + var deleteDocumentResultsEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_DELETED); + + if (hasEventListener(RadiateEvent.DOCUMENT_DELETED)) { + deleteDocumentResultsEvent.data = data; + deleteDocumentResultsEvent.successful = successful; + deleteDocumentResultsEvent.status = successful ? "ok" : "error"; + dispatchEvent(deleteDocumentResultsEvent); + } + } + + /** + * Dispatch asset added event + * */ + public function dispatchAssetAddedEvent(data:Object):void { + var assetAddedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.ASSET_ADDED); + + if (hasEventListener(RadiateEvent.ASSET_ADDED)) { + assetAddedEvent.data = data; + dispatchEvent(assetAddedEvent); + } + } + + /** + * Dispatch asset removed event + * */ + public function dispatchAssetRemovedEvent(data:IDocumentData, successful:Boolean = true):void { + var assetRemovedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.ASSET_REMOVED); + + if (hasEventListener(RadiateEvent.ASSET_REMOVED)) { + assetRemovedEvent.data = data; + dispatchEvent(assetRemovedEvent); + } + } + + /** + * Dispatch target change event + * */ + public function dispatchTargetChangeEvent(target:*, multipleSelection:Boolean = false):void { + if (importingDocument) return; + var targetChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.TARGET_CHANGE, false, false, target, null, null, multipleSelection); + + if (hasEventListener(RadiateEvent.TARGET_CHANGE)) { + targetChangeEvent.selectedItem = target && target is Array ? target[0] : target; + targetChangeEvent.targets = ArrayUtil.toArray(target); + dispatchEvent(targetChangeEvent); + } + } + + /** + * Dispatch scale change event + * */ + public function dispatchScaleChangeEvent(target:*, scaleX:Number = NaN, scaleY:Number = NaN):void { + var scaleChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.SCALE_CHANGE, false, false, target, null, null); + + if (hasEventListener(RadiateEvent.SCALE_CHANGE)) { + scaleChangeEvent.scaleX = scaleX; + scaleChangeEvent.scaleY = scaleY; + dispatchEvent(scaleChangeEvent); + } + } + + /** + * Dispatch document size change event + * */ + public function dispatchDocumentSizeChangeEvent(target:*):void { + var scaleChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_SIZE_CHANGE, false, false, target, null, null); + + if (hasEventListener(RadiateEvent.DOCUMENT_SIZE_CHANGE)) { + dispatchEvent(scaleChangeEvent); + } + } + + /** + * Dispatch preview event + * */ + public function dispatchPreviewEvent(code:String, type:String):void { + var previewEvent:RadiateEvent = new RadiateEvent(RadiateEvent.REQUEST_PREVIEW); + + if (hasEventListener(RadiateEvent.REQUEST_PREVIEW)) { + previewEvent.previewType = type; + previewEvent.value = code; + dispatchEvent(previewEvent); + } + } + + + /** + * Dispatch code updated event. Type is usually "HTML". + * */ + public function dispatchCodeUpdatedEvent(code:String, type:String, openInWindow:Boolean = false):void { + var codeUpdatedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.CODE_UPDATED); + + if (hasEventListener(RadiateEvent.CODE_UPDATED)) { + codeUpdatedEvent.previewType = type; + codeUpdatedEvent.value = code; + codeUpdatedEvent.openInBrowser = openInWindow; + dispatchEvent(codeUpdatedEvent); + } + } + + /** + * Dispatch color selected event + * */ + public function dispatchColorSelectedEvent(color:uint, invalid:Boolean = false):void { + var colorSelectedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.COLOR_SELECTED); + + if (hasEventListener(RadiateEvent.COLOR_SELECTED)) { + colorSelectedEvent.color = color; + colorSelectedEvent.invalid = invalid; + dispatchEvent(colorSelectedEvent); + } + } + + /** + * Dispatch property selected event + * */ + public function dispatchPropertySelectedEvent(property:String, node:MetaData = null):void { + var colorSelectedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROPERTY_SELECTED); + + if (hasEventListener(RadiateEvent.PROPERTY_SELECTED)) { + colorSelectedEvent.property = property; + colorSelectedEvent.selectedItem = node; + dispatchEvent(colorSelectedEvent); + } + } + + /** + * Dispatch color preview event + * */ + public function dispatchColorPreviewEvent(color:uint, invalid:Boolean = false):void { + var colorPreviewEvent:RadiateEvent = new RadiateEvent(RadiateEvent.COLOR_PREVIEW); + + if (hasEventListener(RadiateEvent.COLOR_PREVIEW)) { + colorPreviewEvent.color = color; + colorPreviewEvent.invalid = invalid; + dispatchEvent(colorPreviewEvent); + } + } + + /** + * Dispatch canvas change event + * */ + public function dispatchCanvasChangeEvent(canvas:*, canvasBackgroundParent:*, scroller:Scroller):void { + var targetChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.CANVAS_CHANGE); + + if (hasEventListener(RadiateEvent.CANVAS_CHANGE)) { + dispatchEvent(targetChangeEvent); + } + } + + /** + * Dispatch tool change event + * */ + public function dispatchToolChangeEvent(value:ITool):void { + var toolChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.TOOL_CHANGE); + + if (hasEventListener(RadiateEvent.TOOL_CHANGE)) { + toolChangeEvent.selectedItem = target && target is Array ? target[0] : target; + toolChangeEvent.targets = targets; + toolChangeEvent.tool = value; + dispatchEvent(toolChangeEvent); + } + } + + /** + * Dispatch target change event with a null target. + * */ + public function dispatchTargetClearEvent():void { + var targetChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.TARGET_CHANGE); + + if (hasEventListener(RadiateEvent.TARGET_CHANGE)) { + dispatchEvent(targetChangeEvent); + } + } + + /** + * Dispatch property change event + * */ + public function dispatchPropertyChangeEvent(target:*, changes:Array, properties:Array, multipleSelection:Boolean = false):void { + if (importingDocument) return; + var propertyChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROPERTY_CHANGED, false, false, target, changes, properties, multipleSelection); + + if (hasEventListener(RadiateEvent.PROPERTY_CHANGED)) { + propertyChangeEvent.properties = properties; + propertyChangeEvent.changes = changes; + propertyChangeEvent.multipleSelection = multipleSelection; + propertyChangeEvent.selectedItem = target && target is Array ? target[0] : target; + propertyChangeEvent.targets = ArrayUtil.toArray(target); + dispatchEvent(propertyChangeEvent); + } + } + + /** + * Dispatch object selected event + * */ + public function dispatchObjectSelectedEvent(target:*):void { + var objectSelectedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.OBJECT_SELECTED, false, false, target); + + if (hasEventListener(RadiateEvent.OBJECT_SELECTED)) { + dispatchEvent(objectSelectedEvent); + } + } + + /** + * Dispatch add items event + * */ + public function dispatchAddEvent(target:*, changes:Array, properties:Array, multipleSelection:Boolean = false):void { + if (importingDocument) return; + var event:RadiateEvent = new RadiateEvent(RadiateEvent.ADD_ITEM, false, false, target, changes, properties, multipleSelection); + var length:int = changes ? changes.length : 0; + + if (hasEventListener(RadiateEvent.ADD_ITEM)) { + event.properties = properties; + event.changes = changes; + event.multipleSelection = multipleSelection; + event.selectedItem = target && target is Array ? target[0] : target; + event.targets = ArrayUtil.toArray(target); + + for (var i:int;i<length;i++) { + if (changes[i] is AddItems) { + event.addItemsInstance = changes[i]; + event.moveItemsInstance = changes[i]; + } + } + dispatchEvent(event); + } + } + + /** + * Dispatch add items event + * */ + public function dispatchMoveEvent(target:*, changes:Array, properties:Array, multipleSelection:Boolean = false):void { + if (importingDocument) return; + var event:RadiateEvent = new RadiateEvent(RadiateEvent.MOVE_ITEM, false, false, target, changes, properties, multipleSelection); + var length:int = changes ? changes.length : 0; + + if (hasEventListener(RadiateEvent.MOVE_ITEM)) { + event.properties = properties; + event.changes = changes; + event.multipleSelection = multipleSelection; + event.selectedItem = target && target is Array ? target[0] : target; + event.targets = ArrayUtil.toArray(target); + + for (var i:int;i<length;i++) { + if (changes[i] is AddItems) { + event.addItemsInstance = changes[i]; + event.moveItemsInstance = changes[i]; + } + } + dispatchEvent(event); + } + } + + /** + * Dispatch remove items event + * */ + public function dispatchRemoveItemsEvent(target:*, changes:Array, properties:*, multipleSelection:Boolean = false):void { + var event:RadiateEvent = new RadiateEvent(RadiateEvent.REMOVE_ITEM, false, false, target, changes, properties, multipleSelection); + var length:int = changes ? changes.length : 0; + + if (hasEventListener(RadiateEvent.REMOVE_ITEM)) { + event.properties = properties; + event.changes = changes; + event.multipleSelection = multipleSelection; + event.selectedItem = target && target is Array ? target[0] : target; + event.targets = ArrayUtil.toArray(target); + + for (var i:int;i<length;i++) { + if (changes[i] is AddItems) { + event.addItemsInstance = changes[i]; + event.moveItemsInstance = changes[i]; + } + } + dispatchEvent(event); + } + } + + /** + * Dispatch to invoke property edit event + * */ + public function dispatchTargetPropertyEditEvent(target:Object, changes:Array, properties:Array, multipleSelection:Boolean = false):void { + var propertyEditEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROPERTY_EDIT, false, false, target, changes, properties, null, multipleSelection); + + if (hasEventListener(RadiateEvent.PROPERTY_EDIT)) { + dispatchEvent(propertyEditEvent); + } + } + + /** + * Dispatch document change event + * */ + public function dispatchDocumentChangeEvent(document:IDocument):void { + var documentChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_CHANGE, false, false, document); + + if (hasEventListener(RadiateEvent.DOCUMENT_CHANGE)) { + dispatchEvent(documentChangeEvent); + } + } + + /** + * Dispatch document rename event + * */ + public function dispatchDocumentRenameEvent(document:IDocument, name:String):void { + var documentRenameEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_RENAME, false, false, document); + + if (hasEventListener(RadiateEvent.DOCUMENT_RENAME)) { + dispatchEvent(documentRenameEvent); + } + } + + /** + * Dispatch project rename event + * */ + public function dispatchProjectRenameEvent(project:IProject, name:String):void { + var projectRenameEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECT_RENAME, false, false, project); + + if (hasEventListener(RadiateEvent.PROJECT_RENAME)) { + dispatchEvent(projectRenameEvent); + } + } + + /** + * Dispatch documents set + * */ + public function dispatchDocumentsSetEvent(documents:Array):void { + var documentChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENTS_SET, false, false, documents); + + if (hasEventListener(RadiateEvent.DOCUMENTS_SET)) { + dispatchEvent(documentChangeEvent); + } + } + + /** + * Dispatch document opening event + * */ + public function dispatchDocumentOpeningEvent(document:IDocument, isPreview:Boolean = false):Boolean { + var documentOpeningEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_OPENING, false, true, document); + var dispatched:Boolean; + + if (hasEventListener(RadiateEvent.DOCUMENT_OPENING)) { + dispatched = dispatchEvent(documentOpeningEvent); + } + + return dispatched; + } + + /** + * Dispatch document open event + * */ + public function dispatchDocumentOpenEvent(document:IDocument):void { + var documentOpenEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_OPEN, false, false); + + if (hasEventListener(RadiateEvent.DOCUMENT_OPEN)) { + documentOpenEvent.selectedItem = document; + dispatchEvent(documentOpenEvent); + } + } + + /** + * Dispatch document removed event + * */ + public function dispatchDocumentRemovedEvent(document:IDocument, successful:Boolean = true):void { + var documentRemovedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_REMOVED, false, false); + + if (hasEventListener(RadiateEvent.DOCUMENT_REMOVED)) { + documentRemovedEvent.successful = successful; + documentRemovedEvent.selectedItem = document; + dispatchEvent(documentRemovedEvent); + } + } + + /** + * Dispatch document save as complete event + * */ + public function dispatchProjectSavedEvent(project:IProject):void { + var projectSaveEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECT_SAVED, false, false); + + if (hasEventListener(RadiateEvent.PROJECT_SAVED)) { + + projectSaveEvent.selectedItem = project; + dispatchEvent(projectSaveEvent); + } + } + + /** + * Dispatch document save complete event + * */ + public function dispatchDocumentSaveCompleteEvent(document:IDocument):void { + var documentSaveAsCompleteEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_SAVE_COMPLETE, false, false, document); + + if (hasEventListener(RadiateEvent.DOCUMENT_SAVE_COMPLETE)) { + dispatchEvent(documentSaveAsCompleteEvent); + } + } + + /** + * Dispatch document not saved event + * */ + public function dispatchDocumentSaveFaultEvent(document:IDocument):void { + var documentSaveFaultEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_SAVE_FAULT, false, false, document); + + if (hasEventListener(RadiateEvent.DOCUMENT_SAVE_FAULT)) { + dispatchEvent(documentSaveFaultEvent); + } + } + + /** + * Dispatch document save as cancel event + * */ + public function dispatchDocumentSaveAsCancelEvent(document:IDocument):void { + var documentSaveAsCancelEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_SAVE_AS_CANCEL, false, false, document); + + if (hasEventListener(RadiateEvent.DOCUMENT_SAVE_AS_CANCEL)) { + dispatchEvent(documentSaveAsCancelEvent); + } + } + + + /** + * Dispatch document add event + * */ + public function dispatchDocumentAddedEvent(document:IDocument):void { + var documentAddedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.DOCUMENT_ADDED, false, false, document, null, null); + + if (hasEventListener(RadiateEvent.DOCUMENT_ADDED)) { + dispatchEvent(documentAddedEvent); + } + } + + /** + * Dispatch project closing event + * */ + public function dispatchProjectClosingEvent(project:IProject):void { + var projectClosingEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECT_CLOSING, false, false, project, null, null); + + if (hasEventListener(RadiateEvent.PROJECT_CLOSING)) { + dispatchEvent(projectClosingEvent); + } + } + + /** + * Dispatch project closed event + * */ + public function dispatchProjectOpenedEvent(project:IProject):void { + var projectOpenedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECT_OPENED, false, false, project, null, null); + + if (hasEventListener(RadiateEvent.PROJECT_OPENED)) { + dispatchEvent(projectOpenedEvent); + } + } + + /** + * Dispatch project closed event + * */ + public function dispatchProjectClosedEvent(project:IProject):void { + var projectClosedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECT_CLOSED, false, false, project, null, null); + + if (hasEventListener(RadiateEvent.PROJECT_CLOSED)) { + dispatchEvent(projectClosedEvent); + } + } + + /** + * Dispatch project removed event + * */ + public function dispatchProjectRemovedEvent(project:IProject):void { + var projectRemovedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECT_REMOVED, false, false, project, null, null); + + if (hasEventListener(RadiateEvent.PROJECT_REMOVED)) { + dispatchEvent(projectRemovedEvent); + } + } + + /** + * Dispatch project change event + * */ + public function dispatchProjectChangeEvent(project:IProject, multipleSelection:Boolean = false):void { + var projectChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECT_CHANGE, false, false, project, null, null, multipleSelection); + + if (hasEventListener(RadiateEvent.PROJECT_CHANGE)) { + dispatchEvent(projectChangeEvent); + } + } + + /** + * Dispatch projects set event + * */ + public function dispatchProjectsSetEvent(projects:Array, multipleSelection:Boolean = false):void { + var projectChangeEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECTS_SET, false, false, projects, null, null, multipleSelection); + + if (hasEventListener(RadiateEvent.PROJECTS_SET)) { + dispatchEvent(projectChangeEvent); + } + } + + /** + * Dispatch project created event + * */ + public function dispatchProjectAddedEvent(project:IProject):void { + var projectCreatedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECT_ADDED, false, false, project, null, null); + + if (hasEventListener(RadiateEvent.PROJECT_ADDED)) { + dispatchEvent(projectCreatedEvent); + } + } + + /** + * Dispatch project created event + * */ + public function dispatchProjectCreatedEvent(project:IProject):void { + var projectCreatedEvent:RadiateEvent = new RadiateEvent(RadiateEvent.PROJECT_CREATED, false, false, project, null, null); + + if (hasEventListener(RadiateEvent.PROJECT_CREATED)) { + dispatchEvent(projectCreatedEvent); + } + } + + /** + * Dispatch a history change event + * */ + public function dispatchHistoryChangeEvent(newIndex:int, oldIndex:int):void { + var event:RadiateEvent = new RadiateEvent(RadiateEvent.HISTORY_CHANGE); + + if (hasEventListener(RadiateEvent.HISTORY_CHANGE)) { + event.newIndex = newIndex; + event.oldIndex = oldIndex; + event.historyEventItem = getHistoryItemAtIndex(newIndex); + dispatchEvent(event); + } + } + + /** + * Sets the logging target + * */ + public static function setLoggingTarget(target:AbstractTarget = null, category:String = null, consoleObject:Object = null):void { + + // Log only messages for the classes in the mx.rpc.* and + // mx.messaging packages. + //logTarget.filters=["mx.rpc.*","mx.messaging.*"]; + //var filters:Array = ["mx.rpc.*", "mx.messaging.*"]; + //var filters:Array = ["mx.rpc.*", "mx.messaging.*"]; + + // Begin logging. + if (target) { + logTarget = target; + //logTarget.filters = filters; + logTarget.level = LogEventLevel.ALL; + Log.addTarget(target); + } + + // set reference to logger + if (category) { + log = Log.getLogger(category); + } + else { + log = Log.getLogger(RADIATE_LOG); + } + + if (consoleObject) { + console = consoleObject; + } + + } + + /** + * Creates the list of components and tools. + * */ + public static function initialize():void { + var componentsXML:XML = new XML(new Radii8LibrarySparkAssets.sparkManifestDefaults()); + var toolsXML:XML = new XML(new Radii8LibraryToolAssets.toolsManifestDefaults()); + var inspectorsXML:XML = new XML(new Radii8LibraryInspectorAssets.inspectorsManifestDefaults()); + var devicesXML:XML = new XML(new Radii8LibraryDeviceAssets.devicesManifestDefaults()); + + createSettingsData(); + + createSavedData(); + + createComponentList(componentsXML); + + createInspectorsList(inspectorsXML); + + createToolsList(toolsXML); + + createDevicesList(devicesXML); + } + + /** + * Startup + * */ + public static function startup():void { + + //ExternalInterface.call("Radiate.getInstance"); + ExternalInterface.call("Radiate.instance.setFlashInstance", ExternalInterface.objectID); + + //instance.getLoggedInStatus(); + } + + /** + * Creates the list of components. + * */ + public static function createComponentList(xml:XML):void { + var length:uint; + var items:XMLList; + var className:String; + var skinClassName:String; + var inspectors:Array; + var hasDefinition:Boolean; + var classType:Object; + var includeItem:Boolean; + var attributes:XMLList; + var attributesLength:int; + var defaults:Object; + var propertyName:String; + var item:XML; + + + // get list of component classes + items = XML(xml).component; + + length = items.length(); + + for (var i:int;i<length;i++) { + item = items[i]; + + var name:String = String(item.id); + className = item.attribute("class"); + skinClassName = item.attribute("skinClass"); + //inspectors = item.inspector; + + includeItem = item.attribute("include")=="false" ? false : true; + + + + // check that definitions exist in domain + // skip any support classes + if (className.indexOf("mediaClasses")==-1 && + className.indexOf("gridClasses")==-1 && + className.indexOf("windowClasses")==-1 && + className.indexOf("supportClasses")==-1) { + + hasDefinition = ApplicationDomain.currentDomain.hasDefinition(className); + + if (hasDefinition) { + classType = ApplicationDomain.currentDomain.getDefinition(className); + + // need to check if we have the skin as well + + //hasDefinition = ApplicationDomain.currentDomain.hasDefinition(skinClassName); + + if (hasDefinition) { + + // get default values + if (item.defaults) { + attributes = item.defaults.attributes(); + attributesLength = attributes.length(); + defaults = {}; + + for each (var value:Object in attributes) { + propertyName = String(value.name()); + + if (propertyName=="dataProvider") { + var array:Array = String(value).split(","); + defaults[propertyName] = new ArrayCollection(array); + } + else { + defaults[propertyName] = String(value); + } + } + } + + addComponentType(item.@id, className, classType, inspectors, null, defaults, null, includeItem); + } + else { + log.error("Component skin class, '" + skinClassName + "' not found for '" + className + "'."); + } + } + else { + log.error("Component class not found: " + className); + } + + } + else { + // delete support classes + // may need to refactor why we are including them in the first place + delete items[i]; + length--; + } + } + + // componentDescriptions should now be populated + } + + /** + * Creates the list of inspectors. + * */ + public static function createInspectorsList(xml:XML):void { + var length:uint; + var inspectorsLength:uint; + var items:XMLList; + var className:String; + var skinClassName:String; + var inspectorClassName:String; + var hasDefinition:Boolean; + var classType:Object; + var includeItem:Boolean; + var attributes:XMLList; + var attributesLength:int; + var defaults:Object; + var propertyName:String; + var item:XML; + var inspectorItems:XMLList; + var inspector:XML; + var inspectableClass:InspectableClass; + var inspectorData:InspectorData; + + + // get list of inspector classes + items = XML(xml).item; + + length = items.length(); + + // add inspectable classes to the dictionary + for (var i:int;i<length;i++) { + inspectableClass = new InspectableClass(items[i]); + className = inspectableClass.className; + + if (inspectableClassesDictionary[className]==null) { + inspectableClassesDictionary[className] = inspectableClass; + } + else { + log.warn("Inspectable class, '" + className + "', was listed more than once during import."); + } + + } + + // check that definitions exist in domain + for each (inspectableClass in inspectableClassesDictionary) { + + length = inspectableClass.inspectors.length; + j = 0; + + for (var j:int;j<length;j++) { + inspectorData = inspectableClass.inspectors[j]; + className = inspectorData.className; + + if (inspectorsDictionary[className]==null) { + + hasDefinition = ApplicationDomain.currentDomain.hasDefinition(className); + + if (hasDefinition) { + classType = ApplicationDomain.currentDomain.getDefinition(className); + } + else { + log.error("Inspector class not found: " + className); + } + + // not passing in classType now since we may load it in later dynamically + addInspectorType(inspectorData.name, className, null, inspectorData.icon, defaults); + } + else { + //log.warn("Inspector class: " + className + ", is already in the dictionary"); + } + } + } + + // inspectorsInstancesDictionary should now be populated + } + + + /** + * Creates the list of tools. + * */ + public static function createToolsList(xml:XML):void { + var inspectorClassName:String; + var hasDefinition:Boolean; + var toolClassDefinition:Object; + var inspectorClassDefinition:Object; + var inspectorClassFactory:ClassFactory; + var toolClassFactory:ClassFactory; + var items:XMLList; + var className:String; + var includeItem:Boolean; + var attributes:XMLList; + var length:uint; + var attributesLength:int; + var defaults:Object; + var propertyName:String; + var toolInstance:ITool; + var inspectorInstance:UIComponent; + var name:String; + var cursorItems:XMLList; + var cursorItem:XML; + var cursorName:String; + var cursors:Dictionary; + var cursorsCount:int; + var cursorData:MouseCursorData; + var cursorBitmapDatas:Vector.<BitmapData>; + var cursorBitmap:Bitmap; + var cursorClass:Class; + var cursorID:String; + var cursorX:int; + var cursorY:int; + var item:XML; + + // get list of tool classes + items = XML(xml).tool; + + length = items.length(); + + for (var i:int;i<length;i++) { + item = items[i]; + + name = String(item.id); + className = item.attribute("class"); + inspectorClassName = item.attribute("inspector"); + cursorItems = item..cursor; + + includeItem = item.attribute("include")=="false" ? false : true; + + if (!includeItem) continue; + + hasDefinition = ApplicationDomain.currentDomain.hasDefinition(className); + + if (hasDefinition) { + toolClassDefinition = ApplicationDomain.currentDomain.getDefinition(className); + + + // get default values + if (item.defaults) { + attributes = item.defaults.attributes(); + attributesLength = attributes.length(); + defaults = {}; + + for each (var value:Object in attributes) { + propertyName = String(value.name()); + + if (propertyName=="dataProvider") { + defaults[propertyName] = new ArrayCollection(String(value).split(",")); + } + else { + defaults[propertyName] = String(value); + } + } + } + + // create tool + toolClassFactory = new ClassFactory(toolClassDefinition as Class); + toolClassFactory.properties = defaults; + toolInstance = toolClassFactory.newInstance(); + + + // create inspector + if (inspectorClassName!="") { + hasDefinition = ApplicationDomain.currentDomain.hasDefinition(inspectorClassName); + + if (hasDefinition) { + inspectorClassDefinition = ApplicationDomain.currentDomain.getDefinition(inspectorClassName); + + // Create tool inspector + inspectorClassFactory = new ClassFactory(inspectorClassDefinition as Class); + //classFactory.properties = defaults; + inspectorInstance = inspectorClassFactory.newInstance(); + + } + else { + var errorMessage:String = "Could not find inspector, '" + inspectorClassName + "' for tool, '" + className + "'. "; + errorMessage += "You may need to add a reference to it in RadiateReferences."; + log.error(errorMessage); + } + } + + + cursorsCount = cursorItems.length(); + + if (cursorsCount>0) { + cursors = new Dictionary(false); + } + + // create mouse cursors + for (var j:int=0;j<cursorsCount;j++) { + cursorItem = cursorItems[j]; + cursorName = cursorItem.@name.toString(); + cursorX = int(cursorItem.@x.toString()); + cursorY = int(cursorItem.@y.toString()); + cursorID = cursorName != "" ? className + "." + cursorName : className; + + // Create a MouseCursorData object + cursorData = new MouseCursorData(); + + // Specify the hotspot + cursorData.hotSpot = new Point(cursorX, cursorY); + + // Pass the cursor bitmap to a BitmapData Vector + cursorBitmapDatas = new Vector.<BitmapData>(1, true); + + // Create the bitmap cursor + // The bitmap must be 32x32 pixels or smaller, due to an OS limitation + //CursorClass = Radii8LibraryToolAssets.EyeDropper; + + if (cursorName) { + cursorClass = toolClassDefinition[cursorName]; + } + else { + cursorClass = toolClassDefinition["Cursor"]; + } + + cursorBitmap = new cursorClass(); + + // Pass the value to the bitmapDatas vector + cursorBitmapDatas[0] = cursorBitmap.bitmapData; + + // Assign the bitmap to the MouseCursor object + cursorData.data = cursorBitmapDatas; + + // Register the MouseCursorData to the Mouse object with an alias + Mouse.registerCursor(cursorID, cursorData); + + cursors[cursorName] = {cursorData:cursorData, id:cursorID}; + } + + if (cursorsCount>0) { + mouseCursors[className] = cursors; + } + + //trace("tool cursors:", cursors); + var toolDescription:ComponentDescription = addToolType(item.@id, className, toolClassDefinition, toolInstance, inspectorClassName, null, defaults, null, cursors); + //trace("tool cursors:", toolDescription.cursors); + } + else { + //trace("Tool class not found: " + classDefinition); + log.error("Tool class not found: " + toolClassDefinition); + } + + } + + // toolDescriptions should now be populated + } + + /** + * Creates the list of devices. + * */ + public static function createDevicesList(xml:XML):void { + var includeItem:Boolean; + var items:XMLList; + var length:uint; + var name:String; + var item:XML; + var device:Device; + var type:String; + + const RES_WIDTH:String = "resolutionWidth"; + const RES_HEIGHT:String = "resolutionHeight"; + const USABLE_WIDTH_PORTRAIT:String = "usableWidthPortrait"; + const USABLE_HEIGHT_PORTRAIT:String = "usableHeightPortrait"; + const USABLE_WIDTH_LANDSCAPE:String = "usableWidthLandscape"; + const USABLE_HEIGHT_LANDSCAPE:String = "usableHeightLandscape"; + + + // get list of device classes + items = XML(xml).size; + + length = items.length(); + + for (var i:int;i<length;i++) { + item = items[i]; + + name = item.attribute("name"); + type = item.attribute("type"); + + device = new Device(); + device.name = name; + device.type = type; + + if (type=="device") { + device.ppi = item.attribute("ppi"); + + device.resolutionWidth = item.attribute(RES_WIDTH); + device.resolutionHeight = item.attribute(RES_HEIGHT); + device.usableWidthPortrait = item.attribute(USABLE_WIDTH_PORTRAIT); + device.usableHeightPortrait = item.attribute(USABLE_HEIGHT_PORTRAIT); + device.usableWidthLandscape = item.attribute(USABLE_WIDTH_LANDSCAPE); + device.usableHeightLandscape = item.attribute(USABLE_HEIGHT_LANDSCAPE); + } + else if (type=="screen") { + device.ppi = item.attribute("ppi"); + device.resolutionWidth = item.attribute(RES_WIDTH); + device.resolutionHeight = item.attribute(RES_HEIGHT); + continue; + } + + includeItem = item.attribute("include")=="false" ? false : true; + + deviceCollections.addItem(device); + + } + + // deviceDescriptions should now be populated + } + + /** + * Helper method to get the ID of the mouse cursor by name. + * + * */ + public function getMouseCursorID(tool:ITool, name:String = "Cursor"):String { + var component:ComponentDescription = getToolDescription(tool); + + + if (component.cursors && component.cursors[name]) { + return component.cursors[name].id; + } + + return null; + } + + //---------------------------------- + // target + //---------------------------------- + + /** + * Use setTarget() or setTargets() method to set the target. + * */ + public function get target():Object { + if (_targets.length > 0) + return _targets[0]; + else + return null; + } + + /** + * @private + */ + /*[Bindable] + public function set target(value:Object):void { + if (_targets.length == 1 && target==value) return; + + _targets.splice(0); + + if (value) { + _targets[0] = value; + } + }*/ + + + //---------------------------------- + // targets + //---------------------------------- + + /** + * @private + * Storage for the targets property. + */ + private var _targets:Array = []; + + /** + * Selected targets + * */ + public function get targets():Array { + return _targets; + } + + /** + * Use setTargets() to set the targets + * @private + * */ + /*public function set targets(value:Array):void { + // remove listeners from previous targets + var n:int = _targets.length; + + for (var i:int = n - 1; i >= 0; i--) { + if (_targets[i] == null) { + continue; + } + + //removeHandlers(_targets[i]); + } + + // Strip out null values. + // Binding will trigger again when the null targets are created. + n = value.length; + + for (i = n - 1; i >= 0; i--) { + if (value[i] == null) { + value.splice(i,1); + continue; + } + + //addHandlers(value[i]); + } + + _targets = value; + + }*/ + + //---------------------------------- + // project + //---------------------------------- + + private var _selectedProject:IProject; + + /** + * Reference to the current project + * */ + public function get selectedProject():IProject { + return _selectedProject; + } + + /** + * @private + */ + [Bindable(event="projectChange")] + public function set selectedProject(value:IProject):void { + if (value==_selectedProject) return; + _selectedProject = value; + + } + + //---------------------------------- + // document + //---------------------------------- + + private var _documentsTabNavigator:TabNavigator; + + /** + * Reference to the tab navigator that creates documents + * */ + public function get documentsTabNavigator():TabNavigator { + return _documentsTabNavigator; + } + + /** + * @private + */ + public function set documentsTabNavigator(value:TabNavigator):void { + _documentsTabNavigator = value; + } + + + /** + * Reference to the tab that the document belongs to + * */ + public var documentsContainerDictionary:Dictionary = new Dictionary(true); + + /** + * Reference to the tab that the document preview belongs to + * */ + public var documentsPreviewDictionary:Dictionary = new Dictionary(true); + + private var _selectedDocument:IDocument; + + /** + * Get the current document. + * */ + public function get selectedDocument():IDocument { + return _selectedDocument; + } + + /** + * @private + */ + [Bindable(event="documentChange")] + public function set selectedDocument(value:IDocument):void { + if (value==_selectedDocument) return; + _selectedDocument = value; + } + + /** + * Templates for creating new projects or documents + * */ + [Bindable] + public var templates:Array; + + //---------------------------------- + // documents + //---------------------------------- + + /** + * @private + * Storage for the documents property. + */ + private var _documents:Array = []; + + /** + * Selected documents + * */ + public function get documents():Array { + return _documents; + } + + /** + * Selected documents + * @private + * */ + [Bindable] + public function set documents(value:Array):void { + // the following comments are old possibly irrelevant... + // remove listeners from previous documents + var n:int = _documents.length; + + for (var i:int = n - 1; i >= 0; i--) { + if (_documents[i] == null) { + continue; + } + + //removeHandlers(_documents[i]); + } + + // Strip out null values. + // Binding will trigger again when the null documents are created. + n = value.length; + + for (i = n - 1; i >= 0; i--) { + if (value[i] == null) { + value.splice(i,1); + continue; + } + + //addHandlers(value[i]); + } + + _documents = value; + + } + + + //---------------------------------- + // projects + //---------------------------------- + + + /** + * Reference to the projects belongs to + * */ + public var projectsDictionary:Dictionary = new Dictionary(true); + + /** + * @private + * Storage for the projects property. + */ + private var _projects:Array = []; + + /** + * Selected projects + * */ + public function get projects():Array { + return _projects; + } + + /** + * Selected projects + * @private + * */ + [Bindable] + public function set projects(value:Array):void { + _projects = value; + + } + + private var _attachments:Array = []; + + /** + * Attachments + * */ + [Bindable] + public function get attachments():Array { + return _attachments; + } + + public function set attachments(value:Array):void { + _attachments = value; + } + + private var _assets:ArrayCollection = new ArrayCollection(); + + /** + * Assets + * */ + [Bindable] + public function get assets():ArrayCollection { + return _assets; + } + + public function set assets(value:ArrayCollection):void { + _assets = value; + } + + + private var _toolLayer:IVisualElementContainer; + + /** + * Container that tools can draw too + * */ + public function get toolLayer():IVisualElementContainer { + return _toolLayer; + } + + /** + * @private + */ + public function set toolLayer(value:IVisualElementContainer):void { + _toolLayer = value; + } + + + /** + * Default log target + * */ + public static var defaultLogTarget:AbstractTarget = new RadiateLogTarget(); + + /** + * Attempt to support a console + * */ + public static var logTarget:AbstractTarget; + + private static var _log:ILogger; + + private static var _console:Object; + + public static var SETTINGS_DATA_NAME:String = "settingsData"; + public static var SAVED_DATA_NAME:String = "savedData"; + public static var WP_HOST:String = "http://www.radii8.com"; + public static var WP_PATH:String = "/r8m/"; + public static var WP_USER_PATH:String = ""; + public static var DEFAULT_DOCUMENT_WIDTH:int = 800; + public static var DEFAULT_DOCUMENT_HEIGHT:int = 792; + + public static function getWPURL():String { + return WP_HOST + WP_PATH + WP_USER_PATH; + } + + /** + * Is true when preview is visible. This is manually set. + * Needs refactoring. + * */ + public var isPreviewVisible:Boolean; + + /** + * Settings + * */ + public static var settings:Settings; + + /** + * Settings + * */ + public static var savedData:SavedData; + + /** + * Collection of mouse cursors that can be added or removed to + * */ + [Bindable] + public static var mouseCursors:Dictionary = new Dictionary(true); + + //---------------------------------- + // + // Device Management + // + //---------------------------------- + + /** + * Collection of devices + * */ + [Bindable] + public static var deviceCollections:ArrayCollection = new ArrayCollection(); + + + //---------------------------------- + // + // Tools Management + // + //---------------------------------- + + public var _selectedTool:ITool; + + /** + * Get selected tool. + * */ + public function get selectedTool():ITool { + return _selectedTool; + } + + /** + * Collection of tools that can be added or removed to + * */ + [Bindable] + public static var toolsDescriptions:ArrayCollection = new ArrayCollection(); + + /** + * Add the named tool class to the list of available tools. + * + * Not sure if we should create an instance here or earlier or later. + * */ + public static function addToolType(name:String, className:String, classType:Object, instance:ITool, inspectorClassName:String, icon:Object = null, defaultProperties:Object=null, defaultStyles:Object=null, cursors:Dictionary = null):ComponentDescription { + var definition:ComponentDescription; + var length:uint = toolsDescriptions.length; + var item:ComponentDescription; + + for (var i:uint;i<length;i++) { + item = toolsDescriptions.getItemAt(i) as ComponentDescription; + + // check if it exists already + if (item && item.classType==classType) { + return item; + //return false; + } + } + + definition = new ComponentDescription(); + + definition.name = name; + definition.icon = icon; + definition.className = className; + definition.classType = classType; + definition.defaultStyles = defaultStyles; + definition.defaultProperties = defaultProperties; + definition.instance = instance; + definition.inspectorClassName = inspectorClassName; + definition.cursors = cursors; + + toolsDescriptions.addItem(definition); + + return definition; + } + + /** + * Sets the selected tool + * */ + public function setTool(value:ITool, dispatchEvent:Boolean = true, cause:String = ""):void { + + if (selectedTool) { + selectedTool.disable(); + } + + _selectedTool = value; + + if (selectedTool) { + selectedTool.enable(); + } + + if (dispatchEvent) { + instance.dispatchToolChangeEvent(selectedTool); + } + + } + + /** + * Get tool description. + * */ + public function getToolDescription(instance:ITool):ComponentDescription { + var length:int = toolsDescriptions.length; + var componentDescription:ComponentDescription; + + for (var i:int;i<length;i++) { + componentDescription = ComponentDescription(toolsDescriptions.getItemAt(i)); + + if (componentDescription.instance==instance) { + return componentDescription; + } + } + + return null; + } + + /** + * Get tool by name. + * */ + public function getToolByName(name:String):ComponentDescription { + var length:int = toolsDescriptions.length; + var componentDescription:ComponentDescription; + + for (var i:int;i<length;i++) { + componentDescription = ComponentDescription(toolsDescriptions.getItemAt(i)); + + if (componentDescription.className==name) { + return componentDescription; + } + } + + return null; + } + + /** + * Get tool by type. + * */ + public function getToolByType(type:Class):ComponentDescription { + var length:int = toolsDescriptions.length; + var componentDescription:ComponentDescription; + + for (var i:int;i<length;i++) { + componentDescription = ComponentDescription(toolsDescriptions.getItemAt(i)); + + if (componentDescription.classType==type) { + return componentDescription; + } + } + + return null; + } + + //---------------------------------- + // + // Inspector Management + // + //---------------------------------- + + /** + * Collection of inspectors that can be added or removed to + * */ + [Bindable] + public static var inspectorsDescriptions:ArrayCollection = new ArrayCollection(); + + /** + * Dictionary of classes that have inspectors + * */ + [Bindable] + public static var inspectableClassesDictionary:Dictionary = new Dictionary(); + + /** + * Dictionary of instances of inspectors searched by class name + * */ + [Bindable] + public static var inspectorsDictionary:Dictionary = new Dictionary(); + + /** + * Add the named inspector class to the list of available inspectors + * */ + public static function addInspectorType(name:String, className:String, classType:Object, icon:Object = null, defaults:Object=null):Boolean { + var inspectorData:InspectorData; + + if (inspectorsDictionary[className]==null) { + inspectorData = new InspectorData(); + inspectorData.name = name==null ? className : name; + inspectorData.className = className; + inspectorData.classType = classType; + inspectorData.icon = icon; + inspectorData.defaults = defaults; + inspectorsDictionary[className] = inspectorData; + } + + + return true; + } + + /** + * Gets inspector classes or null if the definition is not found. + * */ + public function getInspectableClassData(className:String):InspectableClass { + var inspectableClass:InspectableClass = inspectableClassesDictionary[className]; + + return inspectableClass; + } + + /** + * Gets an instance of the inspector class or null if the definition is not found. + * */ + public function getInspectorInstance(className:String):IInspector { + var inspectorData:InspectorData = inspectorsDictionary[className]; + + if (inspectorData) { + if (inspectorData.instance) { + return inspectorData.instance; + } + + var instance:IInspector = inspectorData.getInstance(); + + return instance; + + } + + return null; + } + + /** + * Gets an instance of the inspector class or null if the definition is not found. + * */ + public function getInspector(target:Object, domain:ApplicationDomain = null):IInspector { + var className:String; + + if (target) { + className = ClassUtils.getQualifiedClassName(target); + + var instance:IInspector = getInspectorInstance(className); + + return instance; + } + + return null; + } + + /** + * Gets array of inspector data for the given fully qualified class or object + * */ + public function getInspectors(target:Object):Array { + var className:String; + var inspectors:Array; + var inspectorDataArray:Array; + var inspectableClass:InspectableClass; + var length:int; + + if (target==null) return []; + + if (target is Object) { + className = ClassUtils.getQualifiedClassName(target); + + if (target is Application) { + className = ClassUtils.getSuperClassName(target); + } + } + + if (target is String) { + className = String(target); + } + + className = className ? className.split("::").join(".") : className; + + inspectableClass = getInspectableClassData(className); + + if (inspectableClass) { + return inspectableClass.inspectors; + } + + return []; + } + + //---------------------------------- + // + // Scale Management + // + //---------------------------------- + + /** + * Stops on the scale + * */ + public var scaleStops:Array = [.05,.0625,.0833,.125,.1666,.25,.333,.50,.667,1,1.25,1.50,1.75,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]; + + /** + * Increases the zoom of the target application to next value + * */ + public function increaseScale(valueFrom:Number = NaN, dispatchEvent:Boolean = true):void { + var newScale:Number; + var currentScale:Number; + + + if (isNaN(valueFrom)) { + currentScale = Number(DisplayObject(selectedDocument.instance).scaleX.toFixed(4)); + } + else { + currentScale = valueFrom; + } + + //newScale = DisplayObject(document).scaleX; + + for (var i:int=0;i<scaleStops.length;i++) { + if (currentScale<scaleStops[i]) { + newScale = scaleStops[i]; + break; + } + } + + if (i==scaleStops.length-1) { + newScale = scaleStops[i]; + } + + newScale = Number(newScale.toFixed(4)); + + setScale(newScale, dispatchEvent); + + } + + /** + * Decreases the zoom of the target application to next value + * */ + public function decreaseScale(valueFrom:Number = NaN, dispatchEvent:Boolean = true):void { + var newScale:Number; + var currentScale:Number; + + if (isNaN(valueFrom)) { + currentScale = Number(DisplayObject(selectedDocument.instance).scaleX.toFixed(4)); + } + else { + currentScale = valueFrom; + } + + //newScale = DisplayObject(document).scaleX; + + for (var i:int=scaleStops.length;i--;) { + if (currentScale>scaleStops[i]) { + newScale = scaleStops[i]; + break; + } + } + + if (i==0) { + newScale = scaleStops[i]; + } + + newScale = Number(newScale.toFixed(4)); + + setScale(newScale, dispatchEvent); + + } + + /** + * Sets the zoom of the target application to value. + * */ + public function setScale(value:Number, dispatchEvent:Boolean = true):void { + + if (selectedDocument && !isNaN(value) && value>0) { + //DisplayObject(selectedDocument.instance).scaleX = value; + //DisplayObject(selectedDocument.instance).scaleY = value; + selectedDocument.scale = value; + + if (dispatchEvent) { + dispatchScaleChangeEvent(selectedDocument, value, value); + } + } + } + + /** + * Gets the scale of the target application. + * */ + public function getScale():Number { + + if (selectedDocument && selectedDocument.instance && "scaleX" in selectedDocument.instance) { + return Math.max(selectedDocument.instance.scaleX, selectedDocument.instance.scaleY); + } + + return NaN; + } + + /** + * Center the application + * */ + public function centerApplication(vertically:Boolean = true, verticallyTop:Boolean = true, totalDocumentPadding:int = 0):void { + if (!canvasScroller) return; + var viewport:IViewport = canvasScroller.viewport; + var documentVisualElement:IVisualElement = IVisualElement(selectedDocument.instance); + //var contentHeight:int = viewport.contentHeight * getScale(); + //var contentWidth:int = viewport.contentWidth * getScale(); + // get document size NOT scroll content size + var contentHeight:int = documentVisualElement.height * getScale(); + var contentWidth:int = documentVisualElement.width * getScale(); + var newHorizontalPosition:int; + var newVerticalPosition:int; + var needsValidating:Boolean; + var vsbWidth:int = canvasScroller.verticalScrollBar ? canvasScroller.verticalScrollBar.width : 11; + var hsbHeight:int = canvasScroller.horizontalScrollBar ? canvasScroller.horizontalScrollBar.height : 11; + var availableWidth:int = canvasScroller.width;// - vsbWidth; + var availableHeight:int = canvasScroller.height;// - hsbHeight; + + if (LayoutManager.getInstance().isInvalid()) { + needsValidating = true; + //LayoutManager.getInstance().validateClient(canvasScroller as ILayoutManagerClient); + //LayoutManager.getInstance().validateNow(); + } + + + if (vertically) { + // scroller height 359, content height 504, content height validated 550 + // if document is taller than available space and + // verticalTop is true then keep it at the top + if (contentHeight > availableHeight && verticallyTop) { + newVerticalPosition = canvasBackground.y - totalDocumentPadding; + viewport.verticalScrollPosition = Math.max(0, newVerticalPosition); + } + else if (contentHeight > availableHeight) { + newVerticalPosition = (contentHeight + hsbHeight - availableHeight) / 2; + viewport.verticalScrollPosition = Math.max(0, newVerticalPosition); + } + else { + // content height 384, scroller height 359, vsp 12 + newVerticalPosition = (availableHeight + hsbHeight - contentHeight) / 2; + viewport.verticalScrollPosition = Math.max(0, newVerticalPosition); + } + } + + // if width of content is wider than canvasScroller width then center + if (canvasScroller.width < contentWidth) { + newHorizontalPosition = (contentWidth - availableWidth) / 2; + viewport.horizontalScrollPosition = Math.max(0, newHorizontalPosition); + } + else { + //newHorizontalPosition = (contentWidth - canvasScroller.width) / 2; + //viewport.horizontalScrollPosition = Math.max(0, newHorizontalPosition); + } + } + + /** + * Restores the scale of the target application to 100%. + * */ + public function restoreDefaultScale(dispatchEvent:Boolean = true):void { + if (selectedDocument) { + setScale(1, dispatchEvent); + } + } + + /** + * Sets the scale to fit the available space. + * */ + public function scaleToFit(dispatchEvent:Boolean = true):void { + var width:int; + var height:int; + var availableWidth:int; + var availableHeight:int; + var widthScale:Number; + var heightScale:Number; + var newScale:Number; + var documentVisualElement:IVisualElement = selectedDocument ? selectedDocument.instance as IVisualElement : null; + + if (documentVisualElement) { + + //width = DisplayObject(document).width; + //height = DisplayObject(document).height; + width = documentVisualElement.width; + height = documentVisualElement.height; + var vsbWidth:int = canvasScroller.verticalScrollBar ? canvasScroller.verticalScrollBar.width : 20; + var hsbHeight:int = canvasScroller.horizontalScrollBar ? canvasScroller.horizontalScrollBar.height : 20; + availableWidth = canvasScroller.width - vsbWidth*2.5; + availableHeight = canvasScroller.height - hsbHeight*2.5; + + //var scrollerPaddedWidth:int = canvasScroller.width + documentPadding; + //var scrollerPaddedHeight:int = canvasScroller.height + documentPadding; + + // if the visible area is less than our content then scale down + if (height > availableHeight || width > availableWidth) { + heightScale = availableHeight/height; + widthScale = availableWidth/width; + newScale = Math.min(widthScale, heightScale); + width = newScale * width; + height = newScale * height; + } + else if (height < availableHeight && width < availableWidth) { + newScale = Math.min(availableHeight/height, availableWidth/width); + width = newScale * width; + height = newScale * height; + //newScale = Math.min(availableHeight/height, availableWidth/width); + //newScale = Math.max(availableHeight/height, availableWidth/width); + } + + setScale(newScale, dispatchEvent); + + //////////////////////////////////////////////////////////////////////////////// + /*var documentRatio:Number = width / height; + var canvasRatio:Number = availableWidth / availableHeight; + + var newRatio:Number = documentRatio / canvasRatio; + newRatio = canvasRatio / documentRatio; + newRatio = 1-documentRatio / canvasRatio;*/ + + } + } + + //---------------------------------- + // + // Documentation Utility + // + //---------------------------------- + + public static var docsURL:String = "http://flex.apache.org/asdoc/"; + public static var docsURL2:String = "http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/"; + + /** + * Returns the URL to the help document online based on MetaData passed to it. + * */ + public static function getURLToHelp(metadata:MetaData, useBackupURL:Boolean = true):String { + var path:String = ""; + var currentClass:String; + var sameClass:Boolean; + var prefix:String = ""; + var url:String; + var packageName:String; + var declaredBy:String; + var backupURLNeeded:Boolean; + + if (metadata && metadata.declaredBy) { + declaredBy = metadata.declaredBy; + currentClass = declaredBy.replace(/::|\./g, "/"); + + if (declaredBy.indexOf(".")!=-1) { + packageName = declaredBy.split(".")[0]; + if (packageName=="flash") { + backupURLNeeded = true; + } + } + + if (metadata is StyleMetaData) { + prefix = "style:"; + } + else if (metadata is EventMetaData) { + prefix = "event:"; + } + + + path = currentClass + ".html#" + prefix + metadata.name; + } + + if (useBackupURL && backupURLNeeded) { + url = docsURL2 + path; + } + else { + url = docsURL + path; + } + + return url; + } + + //---------------------------------- + // + // Component Management + // + //---------------------------------- + + /** + * Collection of visual elements that can be added or removed to + * */ + [Bindable] + public static var componentDefinitions:ArrayCollection = new ArrayCollection(); + + /** + * Cache for component icons + * */ + [Bindable] + public static var contentCache:ContentCache = new ContentCache(); + + /** + * Add the named component class to the list of available components + * */ + public static function addComponentType(name:String, className:String, classType:Object, inspectors:Array = null, icon:Object = null, defaultProperties:Object=null, defaultStyles:Object=null, enabled:Boolean = true):Boolean { + var definition:ComponentDefinition; + var length:uint = componentDefinitions.length; + var item:ComponentDefinition; + + + for (var i:uint;i<length;i++) { + item = ComponentDefinition(componentDefinitions.getItemAt(i)); + + // check if it exists already + if (item && item.classType==classType) { + return false; + } + } + + + definition = new ComponentDefinition(); + + definition.name = name; + definition.icon = icon; + definition.className = className; + definition.classType = classType; + definition.defaultStyles = defaultStyles; + definition.defaultProperties = defaultProperties; + definition.inspectors = inspectors; + definition.enabled = enabled; + + componentDefinitions.addItem(definition); + + return true; + } + + /** + * Remove the named component class + * */ + public static function removeComponentType(className:String):Boolean { + var definition:ComponentDefinition; + var length:uint = componentDefinitions.length; + var item:ComponentDefinition; + + for (var i:uint;i<length;i++) { + item = ComponentDefinition(componentDefinitions.getItemAt(i)); + + if (item && item.classType==className) { + componentDefinitions.removeItemAt(i); + } + } + + return true; + } + + /** + * Get the component by class name + * */ + public static function getComponentType(className:String, fullyQualified:Boolean = false):ComponentDefinition { + var definition:ComponentDefinition; + var length:uint = componentDefinitions.length; + var item:ComponentDefinition; + + for (v
<TRUNCATED>