http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/LibraryInspector.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/panels/LibraryInspector.mxml b/Radii8Library/src/com/flexcapacitor/views/panels/LibraryInspector.mxml new file mode 100644 index 0000000..e707044 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/panels/LibraryInspector.mxml @@ -0,0 +1,941 @@ +<?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:c="com.flexcapacitor.controls.*" + xmlns:handlers="com.flexcapacitor.handlers.*" + xmlns:collections="com.flexcapacitor.effects.collections.*" + xmlns:status="com.flexcapacitor.effects.status.*" + xmlns:clipboard="com.flexcapacitor.effects.clipboard.*" + xmlns:file="com.flexcapacitor.effects.file.*" + xmlns:fc="com.flexcapacitor.effects.popup.*" + + implements="com.flexcapacitor.views.IInspector" + + width="400" height="300" + > + + <!-- + + The list of components to include come from spark-manifest-defaults.xml + in Radii8LibrarySparkAssets. The include attribute must be set to true for them to be visible. + + The component classes are included by creating a reference to them in Radii8LibrarySparkAssets. + + We create an instance of the class in the mouse down handler. + + + --> + + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.controller.Radiate; + import com.flexcapacitor.events.DragDropEvent; + import com.flexcapacitor.events.RadiateEvent; + import com.flexcapacitor.managers.layoutClasses.LayoutDebugHelper; + import com.flexcapacitor.model.AttachmentData; + import com.flexcapacitor.model.DocumentData; + import com.flexcapacitor.model.IDocument; + import com.flexcapacitor.model.ImageData; + import com.flexcapacitor.services.WPAttachmentService; + import com.flexcapacitor.utils.DisplayObjectUtils; + import com.flexcapacitor.utils.DragManagerUtil; + import com.flexcapacitor.utils.supportClasses.ComponentDefinition; + import com.flexcapacitor.utils.supportClasses.ComponentDescription; + import com.flexcapacitor.views.IInspector; + import com.flexcapacitor.views.windows.DeleteDocumentWindow; + + import mx.core.ClassFactory; + import mx.events.DragEvent; + import mx.events.FlexEvent; + import mx.managers.ISystemManager; + import mx.managers.SystemManagerGlobals; + + import spark.components.Application; + import spark.components.Group; + import spark.components.Image; + import spark.components.Label; + import spark.events.IndexChangeEvent; + import spark.primitives.BitmapImage; + + [Bindable] + private var radiate:Radiate; + + private var target:Object; + + private var dragManagerInstance:DragManagerUtil; + + public var selectedItem:Object; + + public var fileReference:FileReference; + + + /** + * + * */ + protected function creationCompleteHandler(event:FlexEvent):void { + /*radiate = Radiate.getInstance(); + + radiate.addEventListener(RadiateEvent.ATTACHMENTS_RECEIVED, attachmentsReceived, false, 0, true); + radiate.addEventListener(RadiateEvent.ASSET_ADDED, assetAdded, false, 0, true); + radiate.addEventListener(RadiateEvent.ASSET_REMOVED, assetRemoved, false, 0, true); + + updateAssets();*/ + } + + + public function activate():void { + radiate = Radiate.getInstance(); + + radiate.addEventListener(RadiateEvent.ATTACHMENT_UPLOADED, uploadAttachmentResult, false, 0, true); + radiate.addEventListener(RadiateEvent.ATTACHMENTS_RECEIVED, attachmentsReceived, false, 0, true); + radiate.addEventListener(RadiateEvent.ASSET_ADDED, assetAdded, false, 0, true); + radiate.addEventListener(RadiateEvent.ASSET_REMOVED, assetRemoved, false, 0, true); + + updateAssets(); + } + + public function deactivate():void { + if (radiate) { + radiate.removeEventListener(RadiateEvent.ATTACHMENT_UPLOADED, uploadAttachmentResult); + radiate.removeEventListener(RadiateEvent.ATTACHMENTS_RECEIVED, attachmentsReceived); + radiate.removeEventListener(RadiateEvent.ASSET_ADDED, assetAdded); + radiate.removeEventListener(RadiateEvent.ASSET_REMOVED, assetRemoved); + } + } + + protected function targetChangeHandler(event:RadiateEvent):void + { + target = event.selectedItem; + } + + /** + * Listen for drag movement and start dragging if drag tolerance is met + * */ + public function rowGroupMouseDownHandler(event:MouseEvent, data:Object, itemIndex:int):void { + var classFactory:ClassFactory; + var item:ComponentDefinition; + var application:Application; + var component:Object; + var iDocument:IDocument = radiate.selectedDocument; + var rowGroup:Group; + + selectedItem = data; + + item = Radiate.getComponentType("Image"); + + //dropTargetLabel.text = ""; + + rowGroup = event.currentTarget as Group; + + //event.stopImmediatePropagation(); + //list.dragEnabled = false; + + application = iDocument && iDocument.instance ? iDocument.instance as Application : null; + + if (!application) return; + + if (selectedItem is ImageData) { + // if we do this it doesn't show up in event history +/* if (ImageData(selectedItem).bitmapData) { + item.defaultProperties.source = selectedItem.bitmapData; + } + else if (ImageData(selectedItem).url) { + item.defaultProperties.source = selectedItem.url; + }*/ + } + + component = Radiate.createComponentForAdd(iDocument, item); + + + if (!dragManagerInstance) { + dragManagerInstance = new DragManagerUtil(); + } + + rowGroup.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); + rowGroup.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, 0, true); + + //dragManagerInstance.listenForDragBehavior(rowGroup, application, event, component); + dragManagerInstance.listenForDragBehavior(rowGroup, iDocument, event, component); + dragManagerInstance.removeEventListener(DragDropEvent.DRAG_DROP, handleDragDrop); + dragManagerInstance.removeEventListener(DragEvent.DRAG_OVER, handleDragOver); + dragManagerInstance.removeEventListener(DragDropEvent.DRAG_DROP_COMPLETE, handleDragDropComplete); + + dragManagerInstance.addEventListener(DragDropEvent.DRAG_DROP, handleDragDrop); + dragManagerInstance.addEventListener(DragEvent.DRAG_OVER, handleDragOver); + dragManagerInstance.addEventListener(DragDropEvent.DRAG_DROP_COMPLETE, handleDragDropComplete); + + // DRAG DROP + // is continued in + // DragManagerUtil.dragDropHandler() + + // and then in handleDragDrop() here + } + + /** + * Remove mouse handlers from row + * */ + protected function mouseUpHandler(event:MouseEvent):void { + // we need a custom FlexSprite class to do this + /*if (event.currentTarget.eventListeners) { + event.currentTarget.removeAllEventListeners(); + }*/ + + //list.dragEnabled = true; + event.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); + + } + + /** + * Handles drag drop event. This is only the first part of adding to the stage. + * We can prevent automatic adding by calling event.preventDefault(). + * If we do not call preventDefault dragDropComplete is the next event to be called. + * */ + protected function handleDragDrop(event:DragDropEvent):void + { + var component:Object = event.draggedItem; + + // if text based or combo box we need to prevent + // interaction with cursor + + // UPDATE THIS IN DRAG DROP COMPLETE + /* + if (component is TextBase || component is SkinnableTextBase) { + component.mouseChildren = false; + + if ("textDisplay" in component && component.textDisplay) { + component.textDisplay.enabled = false; + } + }*/ + + dragManagerInstance.removeEventListener(DragDropEvent.DRAG_DROP, handleDragDrop); + //dropTargetLabel.text = "Drag drop to:" + dragManagerInstance.dropTargetName; + + dragManagerInstance.removeEventListener(DragEvent.DRAG_OVER, handleDragOver); + } + + private static var _layoutDebugHelper:LayoutDebugHelper; + + public static function get debugHelper():LayoutDebugHelper + { + if (!_layoutDebugHelper) + { + _layoutDebugHelper = new LayoutDebugHelper(); + _layoutDebugHelper.mouseEnabled = false; + var sm:ISystemManager = SystemManagerGlobals.topLevelSystemManagers[0] + sm.addChild(_layoutDebugHelper); + } + return _layoutDebugHelper; + } + + private function deferredInstanceFromFunction():Array { + var label:Label = new Label(); + return [label]; + } + + /** + * Dispatched after drag drop event. Drag drop can be canceled. If it + * is not canceled this event happens. + * */ + protected function handleDragDropComplete(event:DragDropEvent):void { + var o:LayoutDebugHelper = debugHelper; + var component:Object = event.draggedItem; + var image:Image = component as Image; + var attachmentData:AttachmentData = selectedItem as AttachmentData; + var imageData:ImageData = attachmentData as ImageData; + var path:String; + + if (image) { + //image.source = event.draggedItem; + + if (imageData is ImageData) { + path = imageData.url; + + if (path) { + image.width = undefined; + image.height = undefined; + //image.source = null;//force it to show up in change history + Radiate.setProperty(image, "source", path); + } + else if (imageData.bitmapData) { + Radiate.setProperty(image, "source", imageData.bitmapData); + } + } + else { + image.source = ""; + } + + } + /* + // if text based or combo box we need to prevent + // interaction with cursor + if (component is TextBase || component is SkinnableTextBase) { + component.mouseChildren = false; + + if ("textDisplay" in component && component.textDisplay) { + component.textDisplay.enabled = false; + } + } + + if (component is ComboBox) { + if ("textInput" in component && component.textInput.textDisplay) { + component.textInput.textDisplay.enabled = false; + } + } + + // we can't add elements if skinnablecontainer._deferredContentCreated is false + if (component is BorderContainer) { + var factory:DeferredInstanceFromFunction = new DeferredInstanceFromFunction(deferredInstanceFromFunction); + BorderContainer(component).mxmlContentFactory = factory; + //BorderContainer(component).initialize(); + BorderContainer(component).createDeferredContent(); + BorderContainer(component).removeAllElements(); + + // we could probably also do this: + //BorderContainer(component).addElement(new Button()); + + } + + // we need a custom FlexSprite class to do this + // do this after drop + if ("eventListeners" in component && !(component is GroupBase)) { + component.removeAllEventListeners(); + }*/ + + //o.addElement(component as ILayoutElement); + dragManagerInstance.removeEventListener(DragDropEvent.DRAG_DROP_COMPLETE, handleDragDropComplete); + //dropTargetLabel.text = "Drag Complete to:" + dragManagerInstance.dropTargetName; + + + dragManagerInstance.removeEventListener(DragEvent.DRAG_OVER, handleDragOver); + } + + protected function addItemHandler(event:RadiateEvent):void { + //trace("item addedd"); + + //radiate.target = event.eventTarget; + + } + + protected function handleDragOver(event:Event):void { + + //Radiate.log.info("target: " + dragManagerInstance.lastTargetCandidate); + //dropTargetLabel.text = "Drag over: " + dragManagerInstance.dropTargetName; + } + + protected function list_dragStartHandler(event:DragEvent):void { + + } + + protected function attachmentsReceived(event:RadiateEvent):void { + var attachments:Array = event.targets as Array; + + libraryCollection.source = attachments; + } + + + /** + * Pressing enter would retrieve the style value. + * + * This is no longer necessary since values are updated on property change events. + * */ + protected function searchPropertyInput_enterHandler(event:FlexEvent):void { + var searchText:String = filterInput.text; + var item:XML; + + } + + /** + * Move from search text input to properties grid on down arrow key + * */ + protected function filterInput_keyUpHandler(event:KeyboardEvent):void { + /*if (event.keyCode==Keyboard.DOWN) { + propertiesGrid.setFocus(); + if (propertiesGrid.selectedIndex ==-1) { + propertiesGrid.setSelectedIndex(0); + } + }*/ + } + + public var SMALL:String = "small"; + public var MEDIUM:String = "medium"; + public var FULL:String = "full"; + public var THUMBNAIL:String = "thumbnail"; + + public var service:WPAttachmentService; + + protected function smallImage_clickHandler(event:MouseEvent):void { + var selectedItem:AttachmentData = list.selectedItem as AttachmentData; + var imageData:ImageData = selectedItem as ImageData; + + if (imageData) { + imageURLInput.text = imageData.smallURL; + } + } + + protected function thumbnailImage_clickHandler(event:MouseEvent):void { + setTextInputImageURL(THUMBNAIL); + } + + protected function fullImage_clickHandler(event:MouseEvent):void { + setTextInputImageURL(FULL); + } + + // "People are like the things they use the most" + // stereotype = women are better communicators. what??? women or men are better at what they use the most + + protected function mediumImage_clickHandler(event:MouseEvent):void { + + setTextInputImageURL(MEDIUM); + } + + /** + * Set the URL + * */ + public function setTextInputImageURL(value:String):void { + var selectedItem:AttachmentData = list.selectedItem as AttachmentData; + var imageData:ImageData = selectedItem as ImageData; + + if (imageData) { + + if (value==SMALL) { + imageURLInput.text = imageData.smallURL; + } + else if (value==MEDIUM) { + imageURLInput.text = imageData.mediumURL; + } + else if (value==FULL) { + imageURLInput.text = imageData.url; + } + else if (value==THUMBNAIL) { + imageURLInput.text = imageData.thumbnailURL; + } + + //imageURLInput.selectRange(imageURLInput.text.length, imageURLInput.text.length); + imageURLInput.appendText(""); + } + } + + protected function list_changeHandler(event:IndexChangeEvent):void { + var selectedItem:AttachmentData = list.selectedItem as AttachmentData; + var imageData:ImageData = selectedItem as ImageData; + + if (imageData) { + setTextInputImageURL(FULL); + } + + if (selectedItem) { + radiate.dispatchObjectSelectedEvent(selectedItem); + } + } + + protected function openIcon_clickHandler(event:MouseEvent):void { + selectFileToUpload(); + } + + /** + * Select a file for upload + * */ + public function selectFileToUpload():void { + fileReference = new FileReference(); + fileReference.browse(); + fileReference.addEventListener(Event.SELECT, fileSelected, false, 0, true); + fileReference.addEventListener(Event.COMPLETE, fileComplete, false, 0, true); + } + + /** + * File selected + * */ + protected function fileSelected(event:Event):void { + var byteArray:ByteArray = fileReference.data; + + fileReference.load(); + } + + /** + * File load complete + * */ + protected function fileComplete(event:Event):void { + var data:ImageData = new ImageData(); + data.bitmapData; + + } + + /** + * File load complete + * */ + protected function loadFile_completeHandler(event:Event):void { + + var data:ImageData = new ImageData(); + data.bitmapData = loadFile.bitmapData; + data.byteArray = loadFile.data; + data.name = loadFile.currentFile.name; + data.contentType = loadFile.loaderContentType; + data.file = loadFile.currentFile; + + radiate.addAsset(data); + + list.selectedItem = data; + + //uploadAttachment(loadFile.fileReference); + } + + /** + * Upload file + * */ + public function uploadFile(data:DocumentData):void { + + if (false && data && data.file) { + uploadAttachment(data.file); + } + else if (data) { + if (data.id==null) { + uploadAttachment(data); + } + else { + Radiate.log.warn("This item is already uploaded."); + } + } + else { + + } + } + + public var currentUpload:AttachmentData; + + /** + * Create WP service and upload file + * */ + public function uploadAttachment(data:Object):void { + var postID:String; + var imageData:ImageData = data as ImageData; + var fileReference:FileReference = data as FileReference; + + radiate.addEventListener(RadiateEvent.ATTACHMENT_UPLOADED, uploadAttachmentResult, false, 0, true); + + // upload attachment to project + postID = radiate.selectedProject ? radiate.selectedProject.id : null; + + // if project is not available for some reason upload to document + if (postID==null) { + postID = radiate.selectedDocument ? radiate.selectedDocument.id : null; + } + + if (postID==null) { + Radiate.log.info("Please save the document or project first."); + } + + if (fileReference) { + radiate.uploadAttachment(fileReference, postID); + } + else if (imageData) { + currentUpload = imageData; + radiate.uploadAttachment(imageData.byteArray, postID, imageData.name, null, imageData.contentType); // try to upload to an account not document + } + } + + protected function uploadAttachmentResult(event:RadiateEvent):void { + var attachments:Array = event.data as Array; + var data:Object = event.selectedItem; + var attachment:AttachmentData; + var containsName:Boolean; + var length:int = attachments.length; + var iDocument:IDocument = radiate.selectedDocument; + + if (event.successful) { + /*for (var i:int;i<length;i++) { + attachment = attachments[i]; + containsName = currentUpload.name.indexOf(attachment.name)==0; + + if (attachment.name == currentUpload.name || containsName) { + currentUpload.unmarshall(attachment); + break; + } + } + + // might need to loop through all documents in project + DisplayObjectUtils.walkDownComponentTree(iDocument.componentDescription, replaceBitmapData);*/ + } + + // cause the list to update and rerender the rows + libraryCollection.refresh(); + } + + protected function uploadAttachmentFault(event:RadiateEvent):void { + //var message:String = event.message; + } + + protected function refreshIcon_clickHandler(event:MouseEvent):void { + var postID:String = radiate.selectedProject ? radiate.selectedProject.id : null; + var id:int; + + if (postID==null) { + postID = radiate.selectedDocument ? radiate.selectedDocument.id : null; + } + if (postID==null) { + id = 0; + } + else { + id = int(postID); + } + + radiate.getAttachments(id); + } + + protected function assetAdded(event:Event):void { + updateAssets(); + } + + protected function assetRemoved(event:Event):void { + updateAssets(); + } + + private function updateAssets():void { + + // not sure why it's not deleteing the last item + if (radiate.assets.length==0) { + // RangeError: Index '-1' specified is out of bounds. + // - when setting source to empty array before hand + // - assets.source may be bound so when that array item is + // - removed and then remove all is called it may not be found + // - calling refresh before calling remove all + libraryCollection.refresh(); + libraryCollection.removeAll(); + } + else { + libraryCollection.source = radiate.assets.source; + } + } + + ]]> + </fx:Script> + + <fx:Declarations> + <s:ArrayCollection id="libraryCollection"/> + + <!-- SORT BY NAME --> + <handlers:EventHandler eventName="creationComplete" > + <collections:SortCollection target="{libraryCollection}" fields="{['name']}" /> + </handlers:EventHandler> + + <!-- FILTER BY NAME --> + <handlers:EventHandler eventName="change" + targets="{[filterInput,showAllItemsOnEmpty,caseSensitive,searchAtStart]}" + > + <collections:FilterCollection target="{libraryCollection}" + source="{filterInput}" + sourcePropertyName="text" + fieldName="name" + showAllItemsOnEmpty="{showAllItemsOnEmpty.selected}" + caseSensitive="{caseSensitive.selected}" + searchAtStart="{searchAtStart.selected}" + /> + </handlers:EventHandler> + + + <!-- COPY TO THE CLIPBOARD --> + <handlers:EventHandler eventName="click" target="{copyIcon}" setTriggerEvent="true"> + + <clipboard:CopyToClipboard data="{imageURLInput.text}" targetAncestor="{this}" allowNullData="true"> + <clipboard:successEffect> + <status:ShowStatusMessage message="URL copied to the clipboard"/> + </clipboard:successEffect> + <clipboard:noDataEffect> + <status:ShowStatusMessage message="Nothing to copy to the clipboard"/> + </clipboard:noDataEffect> + <clipboard:errorEffect> + <status:ShowStatusMessage message="An error occurred while attempting to copy to the clipboard"/> + </clipboard:errorEffect> + </clipboard:CopyToClipboard> + + </handlers:EventHandler> + + <!-- BROWSE FOR FILE --> + <handlers:EventHandler eventName="click" target="{browseForFileIcon}"> + <file:BrowseForFile id="browseForFile" + fileTypes="png,jpg,jpeg,gif" + targetAncestor="{this}" + allowMultipleSelection="false"> + <file:selectionEffect> + <file:LoadFile id="loadFile" + loadIntoLoader="true" + fileReference="{browseForFile.fileReference}" + loaderComplete="loadFile_completeHandler(event)" + > + + </file:LoadFile> + </file:selectionEffect> + </file:BrowseForFile> + </handlers:EventHandler> + + <!-- SHOW DELETE RESOURCE POP UP --> + <handlers:EventHandler targets="{deleteAttachmentIcon}" eventName="click" + enabled="{list.selectedItem!=null}"> + <fc:OpenPopUp id="openDeleteDocumentPopUp" + popUpType="{DeleteDocumentWindow}" + modalDuration="100" + percentWidth="75" + percentHeight="90" + width="600" + parent="{parentApplication}" + popUpOptions="{{currentState:DeleteDocumentWindow.RESOURCE, documentData:list.selectedItem}}" + /> + </handlers:EventHandler> + </fx:Declarations> + + <!-- + <s:Rect> + <s:fill> + <s:SolidColor color="" + </s:fill> + </s:Rect>--> + + <s:layout> + <s:VerticalLayout paddingLeft="8" paddingRight="8" paddingBottom="8"/> + </s:layout> + + <mx:VDividedBox id="verticalContainer" + width="100%" height="100%" + top="0" + left="8" + right="8" + bottom="4" + > + + <s:Group height="24" + minHeight="24" + maxHeight="60" + width="100%" + > + + <c:SearchTextInput id="filterInput" + left="0" right="0" top="0" + width="100%" + minWidth="60" + prompt="Search" + styleName="inputStyles" + enter="searchPropertyInput_enterHandler(event)" + keyUp="filterInput_keyUpHandler(event)" + /> + + <s:HGroup width="100%" top="32" left="4" verticalAlign="baseline"> + <s:CheckBox id="showAllItemsOnEmpty" label="All" selected="true"/> + <s:CheckBox id="caseSensitive" label="Case" selected="false"/> + <s:CheckBox id="searchAtStart" label="At start" selected="false"/> + <s:Spacer width="100%"/> + <s:Label text="Results: {libraryCollection.length}"/> + </s:HGroup> + </s:Group> + + + <s:List id="list" + width="100%" + height="100%" + labelField="name" + dragEnabled="true" + borderVisible="false" + interactionMode="mouse" + requireSelection="true" + dataProvider="{libraryCollection}" + dragStart="list_dragStartHandler(event)" + change="list_changeHandler(event)" + > + <s:itemRenderer> + <fx:Component> + <s:ItemRenderer width="100%" height="100%" minHeight="22" > + <fx:Script> + <![CDATA[ + import com.flexcapacitor.controller.Radiate; + import com.flexcapacitor.model.AttachmentData; + import com.flexcapacitor.model.ImageData; + + public var imageData:ImageData; + public var attachmentData:AttachmentData; + + override public function set data(value:Object):void { + super.data = value; + var path:String; + attachmentData = value as AttachmentData; + imageData = value as ImageData; + + if (data) { + + if (imageData) { + if (imageData.thumbnailURL) { + iconImage.source = imageData.thumbnailURL; + } + else if (imageData.bitmapData) { + iconImage.source = imageData.bitmapData; + } + } + + } + + // show the upload icon if not uploaded + if (attachmentData && attachmentData.id==null) { + uploadFileIcon.visible = true; + uploadFileIcon.enabled = true; + } + else { + uploadFileIcon.enabled = false; + uploadFileIcon.visible = false; + } + } + + protected function iconImage_ioErrorHandler(event:IOErrorEvent):void { + iconImage.source = "assets/images/components/BorderContainer.png"; + } + + protected function groupMouseDownHandler(event:MouseEvent):void { + outerDocument.rowGroupMouseDownHandler(event, data, itemIndex); + } + + protected function iconImage_securityErrorHandler(event:SecurityErrorEvent):void { + Radiate.log.warn("Library: Icon not found"); + } + + protected function uploadFileIcon_clickHandler(event:MouseEvent):void { + + if (!Radiate.getInstance().uploadAttachmentInProgress) { + uploadFileIcon.enabled = false; + outerDocument.uploadFile(attachmentData); + } + } + + ]]> + </fx:Script> + + <s:HGroup id="rowGroup" + width="100%" + height="100%" + verticalAlign="middle" + paddingLeft="5" + mouseEnabledWhereTransparent="true" + mouseDown="groupMouseDownHandler(event)"> + <s:Image id="iconImage" + smooth="true" + contentLoader="{Radiate.contentCache}" + ioError="iconImage_ioErrorHandler(event)" + securityError="iconImage_securityErrorHandler(event)" + width="16" height="16"/> + <s:Label id="labelDisplay" + fontSize="11"/> + <s:Spacer width="100%"/> + <c:ImageButton id="uploadFileIcon" + source="{Radii8LibraryAssets.upload}" + toolTip="Upload" + click="uploadFileIcon_clickHandler(event)" + visible="false" + /> + <s:Spacer width="1"/> + </s:HGroup> + + </s:ItemRenderer> + </fx:Component> + + </s:itemRenderer> + </s:List> + + + </mx:VDividedBox> + + + <s:HGroup width="100%" + height="24" + minHeight="24" + verticalAlign="middle" + > + + <c:ImageButton id="browseForFileIcon" + source="{Radii8LibraryAssets.newFile}" + toolTip="Add" + /> + + + <s:TextInput id="imageURLInput" + left="0" right="0" top="0" + width="100%" + minWidth="60" + prompt="" + styleName="inputStyles" + /> + + <s:HGroup verticalAlign="bottom"> + + <s:BorderContainer id="thumnailImage" + width="12" height="12" + backgroundColor="#cccccc" + borderVisible="false" + useHandCursor="true" + buttonMode="true" + toolTip="Thumbnail URL" + click="thumbnailImage_clickHandler(event)" + /> + + <!--<s:BorderContainer id="smallImage" + width="12" height="12" + backgroundColor="gray" + borderVisible="false" + useHandCursor="true" + buttonMode="true" + toolTip="Small Image URL" + click="smallImage_clickHandler(event)" + />--> + <s:BorderContainer id="mediumImage" + width="14" height="14" + backgroundColor="#cccccc" + borderVisible="false" + useHandCursor="true" + buttonMode="true" + toolTip="Medium Image URL" + click="mediumImage_clickHandler(event)" + /> + + <s:BorderContainer id="fullImage" + width="14" height="16" + backgroundColor="#cccccc" + borderVisible="false" + useHandCursor="true" + buttonMode="true" + toolTip="Original Image URL" + click="fullImage_clickHandler(event)" + /> + + + </s:HGroup> + <c:ImageButton id="copyIcon" + source="{Radii8LibraryAssets.copy}" + toolTip="Copy the image URL to the Clipboard"/> + + <c:ImageButton id="refreshIcon" + source="{Radii8LibraryAssets.refresh}" + toolTip="Refresh" + click="refreshIcon_clickHandler(event)"/> + + <c:ImageButton id="deleteAttachmentIcon" + source="{Radii8LibraryAssets.trashCan}" + toolTip="Remove Attachment" + /> + </s:HGroup> + + +</s:Group>
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/MetaDataInspector.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/panels/MetaDataInspector.mxml b/Radii8Library/src/com/flexcapacitor/views/panels/MetaDataInspector.mxml new file mode 100644 index 0000000..d773260 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/panels/MetaDataInspector.mxml @@ -0,0 +1,191 @@ +<?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:c="com.flexcapacitor.controls.*" + xmlns:handlers="com.flexcapacitor.handlers.*" + xmlns:collections="com.flexcapacitor.effects.collections.*" + xmlns:components="com.flexcapacitor.components.*" + implements="com.flexcapacitor.views.IInspector" + + minWidth="200" + minHeight="100" + > + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.controller.Radiate; + import com.flexcapacitor.events.RadiateEvent; + import com.flexcapacitor.model.MetaData; + import com.flexcapacitor.utils.ClassUtils; + import com.flexcapacitor.utils.SyntaxHighlighter; + + /** + * Reference to Radiate + * */ + public var radiate:Radiate; + + public var syntaxHighlighter:SyntaxHighlighter; + + public var rawData:String; + + public var lastTarget:Object; + + public function activate():void { + radiate = Radiate.getInstance(); + + radiate.addEventListener(RadiateEvent.PROPERTY_SELECTED, propertySelectedHandler, false, 0, true); + radiate.addEventListener(RadiateEvent.OBJECT_SELECTED, objectSelectedHandler, false, 0, true); + radiate.addEventListener(RadiateEvent.TARGET_CHANGE, targetChangeHandler, false, 0, true); + + if (radiate.target) { + //target = radiate.target; + } + + if (radiate.target) { + updateObject(radiate.target); + } + } + + public function deactivate():void { + + if (radiate) { + radiate.removeEventListener(RadiateEvent.PROPERTY_SELECTED, propertySelectedHandler); + radiate.removeEventListener(RadiateEvent.OBJECT_SELECTED, objectSelectedHandler); + radiate.removeEventListener(RadiateEvent.TARGET_CHANGE, targetChangeHandler); + + } + if (mxTextArea) { + mxTextArea.text = ""; + } + } + + + public function updateObject(object:Object):void { + //rawData = String(object);// ObjectUtil.toString(value); + + if (lastTarget==object || object==null) return; + rawData = ClassUtils.getDescribeType(object); + mxTextArea.text = rawData; + mxTextAreaChangeHandler(); + lastTarget = object; + } + + protected function propertySelectedHandler(event:RadiateEvent):void { + var metadata:MetaData = event.selectedItem as MetaData; + var newData:String; + + //trace("property change event"); + + newData = metadata.raw; + if (rawData==newData) { + //trace("data hasn't changed"); + return; + } + + rawData = newData; + mxTextArea.text = rawData; + mxTextAreaChangeHandler(); + } + + protected function objectSelectedHandler(event:RadiateEvent):void { + var object:Object = event.selectedItem; + updateObject(object); + //var valueObject:Object = ObjectUtil.getClassInfo(object); + //var value:String = ObjectUtil.toString(valueObject); + + //trace("property change event"); + + //if (rawData==value) { + //trace("data hasn't changed"); + // return; + //} + } + + protected function targetChangeHandler(event:RadiateEvent):void { + updateObject(event.selectedItem); + } + + private function mxTextAreaChangeHandler():void { + //trace("change handler:" + getTimer()) + if (!syntaxHighlighter) { + syntaxHighlighter = new SyntaxHighlighter(mxTextArea); + syntaxHighlighter.timerInterval = 20; + syntaxHighlighter.cssString = SyntaxHighlighter.CRIMSON_EDITOR_CSS; + syntaxHighlighter.addEventListener(Event.COMPLETE, completeHandler, false, 0, true); + } + + // do not highlight - it's too slow and slows everything else down + // syntaxHighlighter.highlightCode(); + } + + protected function completeHandler(event:Event):void { + //trace("complete event:" + getTimer()); + } + + + ]]> + </fx:Script> + + + <!--<s:TextArea id="metadataTextArea" + top="8" + focusColor="#585858" + width="100%" height="100%" + fontFamily="Courier New" + borderVisible="false" + paddingTop="8" + fontSize="13" + prompt="No metadata available. Select a property, style or event."> + <s:keyFocusChange> + event.preventDefault(); + event.currentTarget.insertText("\t"); + </s:keyFocusChange> + </s:TextArea>--> + + + + <mx:TextArea id="mxTextArea" + top="8" + left="2" + focusAlpha="0" + fontFamily="Monaco,Menlo,Ubuntu Mono,Consolas,source-code-pro,monospace" + borderVisible="false" + paddingTop="8" + fontSize="12" + width="100%" height="100%" + editable="false" + leading="0" + /> + + <s:Label id="noDataLabel" + top="8" + left="2" + paddingTop="8" + color="#484848" + width="100%" height="100%" + fontSize="13" + visible="{mxTextArea.text==''}" + text="No metadata available. Select a property, style or event."> + </s:Label> + + +</s:Group> http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/Profiling.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/panels/Profiling.mxml b/Radii8Library/src/com/flexcapacitor/views/panels/Profiling.mxml new file mode 100644 index 0000000..d3c191f --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/panels/Profiling.mxml @@ -0,0 +1,660 @@ +<?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:handlers="com.flexcapacitor.handlers.*" + xmlns:status="com.flexcapacitor.effect.status.*" + xmlns:inspectors="com.flexcapacitor.inspectors.*" + + creationComplete="group2_creationCompleteHandler(event)" + click="toggleEnable()" + mouseEnabledWhereTransparent="true" + > + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.data.chart.DataItem; + import com.flexcapacitor.performance.PerformanceMeter; + import com.flexcapacitor.performance.ProfileTest; + import com.flexcapacitor.utils.VectorUtils; + + import flash.utils.clearTimeout; + import flash.utils.getTimer; + + import mx.charts.chartClasses.IAxis; + import mx.events.EffectEvent; + import mx.events.FlexEvent; + + + + public const ANALYSIS_COMPLETE:String = "analysisComplete"; + + /** + * Is true when the component is enabled and remains true until + * the first timer event + * */ + [Bindable] + public var initializing:Boolean; + + /** + * If true shows the chart labels + * */ + public var showLabels:Boolean = true; + + /** + * Delay interval when enabling chart + * */ + private var timeoutInterval:uint; + + [Bindable] + public var columnChartAxisAlpha:Number = .9; + + [Bindable] + public var dataSet:Array; + + [Bindable] + public var labelColor:Number = 0xAAAAAA; + + [Bindable] + public var backgroundLinesAlpha:Number = .5; + + /** + * Max number of items to display + * */ + public var maxCount:int = 10; + + /** + * Timer for data change, rotate and add remove updates + * */ + public var timer:Timer = new Timer(updateIntervalAmount); + + /** + * Length in ms that it takes before changing chart data + * */ + [Bindable] + public var updateIntervalAmount:int = 1500; + + /** + * Amount of time before adding or removing chart data items + * */ + public var addRemoveInterval:int = 10000; + + /** + * Last update time + * */ + public var lastUpdateTime:int; + + /** + * Time since last rotation + * */ + private var rotateLastTime:int; + + /** + * Time since last add remove event + * */ + public var addRemoveLastTime:int; + + /** + * Number of items to display + * */ + public var lastCount:int = 6; + + /** + * Flag indicating when state has changed + * */ + public var chartStateChanged:Boolean; + + /** + * Flag indicating when data needs to change but animation is not finished + * */ + public var scheduleDataChange:Boolean; + + /** + * Flag indicating when to disable the component but let animation finished + * */ + public var scheduleDisableChange:Boolean; + + /** + * Letters used for labels + * */ + public var letters:String = "ACTG"; + + /** + * Placement of ticks on the charts + * */ + [Bindable] + [Inspectable(enumeration="inside,outside,cross,none")] + public var tickPlacement:String = "outside"; + + public var chartSeriesDurationChanged:Boolean; + + private var _chartSeriesDuration:int = 1000; + + /** + * Chart series duration + * */ + [Bindable] + public function get chartSeriesDuration():int { + return _chartSeriesDuration; + } + + /** + * @private + */ + public function set chartSeriesDuration(value:int):void { + _chartSeriesDuration = value; + chartSeriesDurationChanged = true; + } + + + private var _enable:Boolean; + + public function get enable():Boolean { + return _enable; + } + + /** + * @private + */ + public function set enable(value:Boolean):void { + //trace("chart enable= " + value); + if (_enable==value) return; + + _enable = value; + + if (value) { + //columnChart.enabled = true; + + if (dataSet==null) { + generateData(); + } + + // run through setting values + resetCharts(); + + columnChart.enabled = true; + } + + else { + timer.stop(); + + if (pieChartSeriesEffect.isPlaying || chartSeriesEffect.isPlaying) { + scheduleDisableChange = true; + } + else { + //clearDataSet(dataSet); + //pieChartSeriesEffect.stop(); + //chartSeriesEffect.stop(); + columnChart.enabled = false; + } + } + + + + // initiates the first call to update timer handler + //timeoutInterval = setTimeout(timerHandler, 15); + } + + /** + * + * */ + public function toggleEnable():void { + return; + //enable = !enable; + if (!columnChart.enabled) { + enableSequence.play(); + } + else { + disableSequence.play(); + } + } + + + /** + * Resets the timer and data + * */ + private function resetCharts():void { + clearTimeout(timeoutInterval); + + + if (enable) { + + // reset last time something happened times + addRemoveLastTime = getTimer(); + rotateLastTime = getTimer(); + + + // reset and start timer + timer.reset(); + timer.start(); + + initializing = true; + } + else { + timer.stop(); + } + } + + protected function button2_clickHandler(event:MouseEvent):void + { + var vector:Vector.<int> = new Vector.<int>(1000000); + var usePush:Boolean = false; + var result:Array = []; + var length:uint = vector.length; + + PerformanceMeter.start("Test1"); + var time:int = getTimer(); + + for(var i:int = 0; i < length; i++){ + result[i] = vector[i]; + } + + time = getTimer() - time; + PerformanceMeter.stop("Test1"); + var profileTest:ProfileTest = PerformanceMeter.getTest("Test1"); + timestamps.source = profileTest.timestampsArray; + timestamps.refresh(); + //trace("time = ", time); + } + + /** + * Generates data + * */ + private function generateData():void { + //trace("generating Data"); + + /*if (currentState==LINE_STATE) { + if (lastCount <8) { + lastCount = 8; + } + + generateLineData(); + } + else {*/ + generateChartData(); + //} + } + + /** + * Generates generic chart data + * */ + public function generateChartData():void { + var newData:Array = []; + + var X:Number = Math.random()*100 - 50; + var Y:Number = X - Math.random() * 10; + var V:Number = Math.random()*100; + + + for (var i:int = 0;i<lastCount;i++) { + X = Math.random()*100; + Y = Math.random()*100; + V = Math.random()*10; + + newData.push(new DataItem(X,Y,V)); + } + + dataSet = newData; + } + + protected function button1_clickHandler(event:MouseEvent):void + { + //timestamps.source = showMessage.profileData; + } + + protected function showMessage_profileDataUpdateHandler(event:Event):void + { + //trace(event.currentTarget.profileData); + } + + public function profileData(testName:String):Array { + var test:ProfileTest = PerformanceMeter.getTest(testName); + + if (test && test.timestamps.length) { + var array:Array = test.timestamps as Array; + return VectorUtils.vectorToArray(test.timestamps); + } + return []; + } + + protected function group2_creationCompleteHandler(event:FlexEvent):void { + timer.addEventListener(TimerEvent.TIMER, timerHandler); + generateData(); + } + + protected function timerHandler(event:TimerEvent = null):void { + var time:int = getTimer(); + + //trace("TIMER UPDATE - " + String(time - lastUpdateTime)); + + // if state changed check for timer delay change + + + // adding new items + if (time>addRemoveLastTime+addRemoveInterval) { + //trace("adding new items"); + addRemoveLastTime = time; + lastCount = Math.random() * maxCount+3; + } + + // prevents data changes when animations are already running + if (chartSeriesEffect.isPlaying || pieChartSeriesEffect.isPlaying) { + scheduleDataChange = true; + } + else { + generateData(); + } + + if (timer.currentCount>15) { + dispatchEvent(new Event(ANALYSIS_COMPLETE)); + } + + initializing = false; + + lastUpdateTime = getTimer(); + } + + protected function chartSeriesEffect_effectEndHandler(event:EffectEvent):void { + + /* if (checkMe) { + trace("checking"); + } */ + if (chartSeriesDurationChanged) { + //trace('effect ended duration changed:' + getTimer()); + + chartSeriesEffect.duration = chartSeriesDuration; + pieChartSeriesEffect.duration = chartSeriesDuration; + chartSeriesDurationChanged = false; + } + else { + //trace('chart effect ended:' + getTimer()); + } + + // disable + if (scheduleDisableChange) { + //clearDataSet(dataSet); + //trace('scheduleDisableChange:' + getTimer()); + scheduleDisableChange = false; + enable = false;// try again + return; + } + + // change data + if (scheduleDataChange) { + //trace('scheduleDataChange:' + getTimer()); + generateData(); + scheduleDataChange = false; + } + + } + + + public function axisLabelFunction(labelValue:Object, previousValue:Object, axis:IAxis):String { + var characters:int = String(labelValue).length; + + if (!showLabels) { + return " "; + } + + if (characters<2) { + //trace("value"); + return "AB" + String(labelValue); + } + else if (characters<3) { + return "A" + String(labelValue); + } + + return String(labelValue); + } + + public function verticalAxisLabelFunction(labelValue:Object, previousValue:Object, axis:IAxis):String { + var characters:int = String(labelValue).length; + + + if (!showLabels) { + return " "; + } + + + //return "â¢"; + if (characters<2) { + //trace("value"); + return " " + String(labelValue); + } + else if (characters<3) { + return " " + String(labelValue); + } + + return String(labelValue); + } + + private function clearDataSet(dataSet:Array):void { + dataSet = null; return; + for (var i:int;i<dataSet.length;i++) { + var item:DataItem = dataSet[i] as DataItem; + item.x = 0; + item.y = 0; + item.v = 0; + } + } + + + public function get disableTimers():Boolean { + return true; + } + + public function set disableTimers(value:Boolean):void { + //trace("disable timers A"); + timer.stop(); + //trace("disable timers B"); + } + + ]]> + </fx:Script> + + + <fx:Declarations> + <handlers:EventHandler eventName="creationComplete" target="{this}" > + + <s:Fade startDelay="1000" target="{awesomeLabel}" alphaTo="1" alphaFrom="0"/> + <s:Pause duration="1000"/> + <s:Fade target="{awesomeLabel}" alphaTo="0" alphaFrom="1"/> + + </handlers:EventHandler> + + <s:ArrayCollection id="timestamps" /> + + <mx:SeriesInterpolate id="chartSeriesEffect" + duration="1000" + elementOffset="15" + minimumElementDuration="200" + effectEnd="chartSeriesEffect_effectEndHandler(event)"/> + + <mx:SeriesInterpolate id="pieChartSeriesEffect" + duration="1000" + elementOffset="0" + minimumElementDuration="0" + effectEnd="chartSeriesEffect_effectEndHandler(event)"/> + + <s:SolidColorStroke id="axisStroke" color="#ff000" weight="4"/> + <s:SolidColorStroke id="lineStroke" color="#ffd000" weight="4"/> + <s:SolidColorStroke id="tickStroke" color="#ffffff" alpha=".5" /> + <s:SolidColorStroke id="backgroundLineStroke" + color="#ffffff" + weight="0" + alpha="{backgroundLinesAlpha}"/> + </fx:Declarations> + + <s:states> + <s:State name="column"/> + <s:State name="columnOff"/> + </s:states> + + <s:transitions> + + <s:Transition id="transitionOn" fromState="portraitOff" toState="portraitOn" > + <s:Sequence id="enableSequence" > + + <!--<s:SetAction target="{this}" property="dataSet" value="{null}" />--> + <s:SetAction target="{columnChart}" property="enabled" value="false"/> + <s:SetAction target="{this}" property="visible" value="true"/> + <s:Pause duration="1000"/> + <s:SetAction target="{this}" property="enable" value="true"/> + + </s:Sequence> + </s:Transition> + + <s:Transition id="transitionOff" fromState="portraitOn" toState="portraitOff" > + <s:Sequence id="disableSequence" > + + <s:SetAction target="{this}" property="disableTimers" value="false"/> + <s:Pause duration="1000"/> + <!--<s:SetAction target="{this}" property="dataSet" value="{null}" />--> + <s:Pause duration="2500"/> + <s:SetAction target="{this}" property="enable" value="false"/> + + </s:Sequence> + </s:Transition> + </s:transitions> + + <s:layout> + <s:BasicLayout /> + </s:layout> + + <!--<s:Button id="button1" label="Test" click="button1_clickHandler(event)"/>--> + + <!-- COLUMN CHART --> + <mx:ColumnChart id="columnChart" + includeIn="column" + enabled="false" + width="100%" height="100%" + dataProvider="{dataSet}" + color="{labelColor}" + bottom="0" + > + + <!--<mx:fill> + <s:SolidColor color="#ff0000"/> + </mx:fill>--> + + <mx:backgroundElements> + <fx:Array> + <mx:GridLines alpha="{backgroundLinesAlpha}" gridDirection="both"/> + </fx:Array> + </mx:backgroundElements> + + <mx:series> + <mx:ColumnSeries showDataEffect="{chartSeriesEffect}" + yField="x" + > + <mx:fill> + <s:SolidColor color="#2da6e9"/> + </mx:fill> + </mx:ColumnSeries> + </mx:series> + + <mx:verticalAxis> + <mx:LinearAxis id="verticalColumnAxisRenderer" + alignLabelsToInterval="true" + direction="normal" + interval="1" + autoAdjust="true" + baseAtZero="false" + minimum="1" maximum="106" + labelFunction="verticalAxisLabelFunction" + /> + </mx:verticalAxis> + + <mx:horizontalAxis> + <mx:LinearAxis id="horizontalColumnAxisRenderer" + alignLabelsToInterval="true" + direction="normal" + interval="1" + autoAdjust="false" + baseAtZero="true" + labelFunction="axisLabelFunction" + /> + </mx:horizontalAxis> + + + <mx:verticalAxisRenderers> + <mx:AxisRenderer axis="{verticalColumnAxisRenderer}" + showLabels="true" + showLine="true" + canDropLabels="true" + tickPlacement="{tickPlacement}" + tickStroke="{tickStroke}" + axisStroke="{backgroundLineStroke}" + placement="left" + alpha="{columnChartAxisAlpha}" + /> + <mx:AxisRenderer axis="{verticalColumnAxisRenderer}" + showLabels="true" + showLine="true" + canDropLabels="true" + tickPlacement="{tickPlacement}" + placement="right" + tickStroke="{tickStroke}" + axisStroke="{backgroundLineStroke}" + alpha="{columnChartAxisAlpha}" + /> + </mx:verticalAxisRenderers> + + <mx:horizontalAxisRenderers> + <mx:AxisRenderer axis="{horizontalColumnAxisRenderer}" + showLabels="true" + showLine="true" + canDropLabels="true" + axisStroke="{backgroundLineStroke}" + tickStroke="{tickStroke}" + tickPlacement="{tickPlacement}" + placement="top" + alpha="{columnChartAxisAlpha}" + /> + <mx:AxisRenderer axis="{horizontalColumnAxisRenderer}" + showLabels="true" + showLine="true" + canDropLabels="true" + axisStroke="{backgroundLineStroke}" + tickStroke="{tickStroke}" + tickPlacement="{tickPlacement}" + placement="bottom" + alpha="{columnChartAxisAlpha}" + /> + </mx:horizontalAxisRenderers> + </mx:ColumnChart> + + <s:Label id="awesomeLabel" + text="Awesome" + horizontalCenter="0" + top="24" + color="#555555" + visible="false"/> + + <!--<mx:CartesianChart width="100%" height="100%" > + + <mx:series> + <mx:AreaSeries dataProvider="{timestamps}" xField="startTime" yField="duration" displayName="Display Name"/> + </mx:series> + </mx:CartesianChart>--> + + +</s:Group> http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/ProjectInspector.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/panels/ProjectInspector.mxml b/Radii8Library/src/com/flexcapacitor/views/panels/ProjectInspector.mxml new file mode 100644 index 0000000..7361e35 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/panels/ProjectInspector.mxml @@ -0,0 +1,336 @@ +<?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:views="com.flexcapacitor.views.*" + xmlns:c="com.flexcapacitor.controls.*" + xmlns:fc="com.flexcapacitor.effects.popup.*" + xmlns:e="com.flexcapacitor.handlers.*" + + width="200" height="100%" + implements="com.flexcapacitor.views.IInspector" + > + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.controller.Radiate; + import com.flexcapacitor.events.RadiateEvent; + import com.flexcapacitor.model.DocumentData; + import com.flexcapacitor.model.IProject; + import com.flexcapacitor.views.windows.DeleteDocumentWindow; + import com.flexcapacitor.views.windows.PublishWindow; + + import spark.events.IndexChangeEvent; + + [Bindable] + private var radiate:Radiate; + + + + public function activate():void { + radiate = Radiate.instance; + + radiate.addEventListener(RadiateEvent.PROJECT_CHANGE, projectChangeHandler, false, 0, true); + radiate.addEventListener(RadiateEvent.PROJECT_ADDED, projectCreatedHandler, false, 0, true); + radiate.addEventListener(RadiateEvent.PROJECT_CREATED, projectCreatedHandler, false, 0, true); + radiate.addEventListener(RadiateEvent.PROJECT_REMOVED, projectRemovedHandler, false, 0, true); + radiate.addEventListener(RadiateEvent.PROJECT_DELETED, projectRemovedHandler, false, 0, true); + radiate.addEventListener(RadiateEvent.PROJECT_SAVED, projectSavedHandler, false, 0, true); + + + radiate.addEventListener(RadiateEvent.DOCUMENT_ADDED, documentChangedHandler, false, 0, true); + radiate.addEventListener(RadiateEvent.DOCUMENT_REMOVED, documentChangedHandler, false, 0, true); + radiate.addEventListener(RadiateEvent.DOCUMENT_DELETED, documentChangedHandler, false, 0, true); + + update(); + } + + public function deactivate():void { + if (radiate) { + radiate.removeEventListener(RadiateEvent.PROJECT_CHANGE, projectChangeHandler); + radiate.removeEventListener(RadiateEvent.PROJECT_ADDED, projectCreatedHandler); + radiate.removeEventListener(RadiateEvent.PROJECT_CREATED, projectCreatedHandler); + radiate.removeEventListener(RadiateEvent.PROJECT_REMOVED, projectRemovedHandler); + radiate.removeEventListener(RadiateEvent.PROJECT_DELETED, projectRemovedHandler); + radiate.removeEventListener(RadiateEvent.PROJECT_SAVED, projectSavedHandler); + + + radiate.removeEventListener(RadiateEvent.DOCUMENT_ADDED, documentChangedHandler); + radiate.removeEventListener(RadiateEvent.DOCUMENT_REMOVED, documentChangedHandler); + radiate.removeEventListener(RadiateEvent.DOCUMENT_DELETED, documentChangedHandler); + } + } + + protected function update():void { + + if (radiate.selectedProject) { + updateSelectedItem(radiate.selectedProject); + } + } + + /** + * + * */ + private function labelFunction(data:Object):String { + return data.name; + } + + /** + * + * */ + protected function projectChangeHandler(event:RadiateEvent):void { + //updateProjects(); + updateSelectedItem(event.selectedItem as IProject); + } + + private function updateProjects():void { + projects.refresh(); + + // must call validate now so selected index doesn't revert if a new project is selected + list.validateNow(); + } + + private function updateSelectedItem(project:IProject):void { + list.selectedItem = project; + } + + public function projectCreatedHandler(event:RadiateEvent):void { + updateProjects(); + } + + protected function list_changeHandler(event:IndexChangeEvent):void { + var project:IProject = list.selectedItem ? IProject(list.selectedItem) : null; + + if (project && !project.isOpen) { + radiate.openProject(project); + } + + if (project) { + radiate.setProject(project); + } + } + + protected function publishButton_clickHandler(event:MouseEvent):void { + + } + + protected function saveProjectIcon_clickHandler(event:MouseEvent):void { + radiate.saveProject(radiate.selectedProject); + //radiate.save(); + radiate.saveSettings(); + } + + protected function getSavedProjectsIcon_clickHandler(event:MouseEvent):void { + radiate.getSavedData(); + radiate.getSettingsData(); + } + /* + protected function deleteProjectIcon_clickHandler(event:MouseEvent):void { + var selectedProject:IProject = list.selectedItem as IProject; + + if (selectedProject) { + radiate.removeProject(selectedProject); + } + else { + Radiate.log.info("Please select a project"); + } + }*/ + + protected function newProjectIcon_clickHandler(event:MouseEvent):void { + //radiate.createProject(); + //radiate.addProject(radiate.createProject(), true, true, true); + radiate.createBlankDemoDocument(); + } + + protected function removeSavedDataIcon_clickHandler(event:MouseEvent):void { + radiate.removeSavedData(); + radiate.removeSavedSettings(); + } + + /** + * Handle when a project has been removed + * */ + protected function projectRemovedHandler(event:Event):void { + updateProjects(); + + if (radiate.projects.length>0) { + radiate.setProject(radiate.projects[0], true); + } + } + + protected function closeProjectIcon_clickHandler(event:MouseEvent):void { + var project:IProject = list.selectedItem ? IProject(list.selectedItem) : null; + + if (project) { + radiate.closeProject(project); + } + } + + protected function openProjectsIcon_clickHandler(event:MouseEvent):void { + var project:IProject = list.selectedItem ? IProject(list.selectedItem) : null; + + if (project) { + radiate.openProject(project, DocumentData.INTERNAL_LOCATION); + } + } + + // HACK TO Mark project needs saved + protected function documentChangedHandler(event:RadiateEvent):void { + + if (radiate.selectedProject) { + radiate.selectedProject.checkProjectHasChanged(); + } + } + + + // HACK TO Mark project needs saved + protected function projectSavedHandler(event:Event):void { + + if (radiate.selectedProject) { + radiate.selectedProject.checkProjectHasChanged(); + } + } + + protected function autoSaveToggle_clickHandler(event:MouseEvent):void { + radiate.enableAutoSave = autoSaveToggle.selected; + } + + ]]> + </fx:Script> + + <fx:Declarations> + <s:ArrayCollection id="projects" source="{radiate.projects}"/> + <s:ArrayCollection id="projectsFiltersTypes"> + <fx:Array> + <fx:String>All Projects</fx:String> + <fx:String>Open Projects</fx:String> + </fx:Array> + </s:ArrayCollection> + + <e:EventHandler eventName="click" target="{publishButton}"> + <fc:OpenPopUp popUpType="{PublishWindow}" modalDuration="250"/> + </e:EventHandler> + + <!--- show delete project popup --> + <e:EventHandler targets="{deleteProjectIcon}" eventName="click" > + <fc:OpenPopUp id="openDeleteProjectPopUp" + popUpType="{DeleteDocumentWindow}" + modalDuration="100" + percentWidth="75" + percentHeight="90" + width="600" + parent="{parentApplication}" + popUpOptions="{{currentState:'project',documentData:list.selectedItem}}" + /> + </e:EventHandler> + </fx:Declarations> + + <s:layout> + <s:VerticalLayout paddingLeft="5" paddingRight="5" paddingBottom="5"/> + </s:layout> + + <s:ButtonBar id="projectFilters" + requireSelection="true" + selectedIndex="0" + labelField="name" + dataProvider="{projectsFiltersTypes}" + includeInLayout="false" + visible="false" + > + </s:ButtonBar> + + <s:List id="list" + focusAlpha="0" + minHeight="20" + width="100%" + height="100%" + labelFunction="labelFunction" + borderAlpha=".2" + dataProvider="{projects}" + change="list_changeHandler(event)" + itemRenderer="com.flexcapacitor.views.renderers.EditableProjectRenderer" + > + + </s:List> + + <s:HGroup width="100%" + height="24" + minHeight="24" + verticalAlign="middle" + > + <s:Button id="publishButton" + label="Publish" + visible="false" + includeInLayout="false"/> + + <c:ImageButton id="removeSavedDataIcon" + source="{Radii8LibraryAssets.clear}" + toolTip="Remove All Locally Saved Projects and Documents" + click="removeSavedDataIcon_clickHandler(event)" + visible="false" + includeInLayout="false" + /> + <c:ImageButton id="getProjectsIcon" + source="{Radii8LibraryAssets.openFolder}" + toolTip="Load all locally Saved Projects and documents" + click="getSavedProjectsIcon_clickHandler(event)" + visible="false" + includeInLayout="false" + /> + <s:CheckBox id="autoSaveToggle" + selected="{radiate.enableAutoSave}" + useHandCursor="true" + buttonMode="true" + enabled="true" + toolTip="Enables auto save" + label="Auto Save" + click="autoSaveToggle_clickHandler(event)" + /> + + <s:Spacer width="100%"/> + <!--<c:ImageButton id="closeProjectIcon" + source="{Radii8LibraryAssets.closedFolder}" + toolTip="Close Project" + click="closeProjectIcon_clickHandler(event)" + /> + <c:ImageButton id="openProjectsIcon" + source="{Radii8LibraryAssets.openFolder}" + toolTip="Open Project" + click="openProjectsIcon_clickHandler(event)" + />--> + <c:ImageButton id="saveProjectIcon" + source="{Radii8LibraryAssets.save}" + toolTip="Save Project" + click="saveProjectIcon_clickHandler(event)" + height="15" + /> + <c:ImageButton id="newProjectIcon" + source="{Radii8LibraryAssets.newFile}" + toolTip="New Project" + click="newProjectIcon_clickHandler(event)" + /> + <c:ImageButton id="deleteProjectIcon" + source="{Radii8LibraryAssets.trashCan}" + toolTip="Remove Project" + /> + </s:HGroup> + +</s:Group>