http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/PropertyInspector.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/panels/PropertyInspector.mxml b/Radii8Library/src/com/flexcapacitor/views/panels/PropertyInspector.mxml new file mode 100644 index 0000000..7fac6a2 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/panels/PropertyInspector.mxml @@ -0,0 +1,1629 @@ +<?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.*" + + minWidth="100" + minHeight="100" + creationComplete="creationCompleteHandler(event)" + > + + + <!-- + This is a standard properties grid that is showing property and value + except that the editor (color picker, text input, etc) is + in the footer rather than next to the view. + + There is a second view that attempts to put the editor next to the + property. This sort of works but is CPU intensive and causes slow + down. This may be because it has hundreds of properties or + another cause. The idea then would be to specify the properties + in the spark or inspectors manifest file and only show those. + Or it would show only the properties defined on it's self. + For example, if it's a Button it will show only the Button + class properties but not ButtonBase, UIComponent and so on. + This has its limitations though. What about size and position? + In that case, the common properties from the inherited classes + would have to be specified. So Button would show all of it's + properties, then any properties on ButtonBase that were specified + as useful would be shown and then add any properties on UIComponent + that were specified as useful would be shown. + + For Button this would look like this: + - + Label - Part of Button base + - + Width - Part of UIComponent + Height + X + Y + + Unfortunately there is the order and grouping to keep in mind. + + The third view would be custom property inspectors based on type or class. + This is defined in the inspectors manifest file. It specifies the views to + display by class name or URL. + + + One of the current problems is that the component or class and it's + description is in XML still in some locations and not stored anywhere else. + We use describeType to get the properties, styles, events and inheritence. + Using XML is relatively heavy, slow and is not typed. We use this + information to dynamically build the inspectors for color, numbers, boolean + and enumerated values. + + It should be refactored. For example, class information should be globally accessable, + and return a strong data type. It should have look up for getting the + inspector type (color, boolean, text inspector etc) and for setting it's value. + + + + TODO: + - do not update if not visible or is not active tab + - add refresh button + - display read only property + - filter to show only the properties that we specify + - show custom views when defined + - add better way to switch between views + --> + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.controller.Radiate; + import com.flexcapacitor.events.RadiateEvent; + import com.flexcapacitor.model.AccessorMetaData; + import com.flexcapacitor.model.MetaData; + import com.flexcapacitor.model.StyleMetaData; + import com.flexcapacitor.utils.ClassUtils; + import com.flexcapacitor.utils.DisplayObjectUtils; + import com.flexcapacitor.utils.InspectorUtils; + import com.flexcapacitor.utils.StringUtils; + import com.flexcapacitor.views.renderers.BooleanRenderer; + import com.flexcapacitor.views.renderers.ColorPickerRenderer; + import com.flexcapacitor.views.renderers.ComboBoxRenderer; + import com.flexcapacitor.views.renderers.NumberRenderer; + import com.flexcapacitor.views.renderers.TextRenderer; + + import flash.utils.getTimer; + + import mx.collections.XMLListCollection; + import mx.core.IFlexModule; + import mx.core.IFlexModuleFactory; + import mx.core.UIComponent; + import mx.effects.effectClasses.PropertyChanges; + import mx.events.FlexEvent; + import mx.utils.DescribeTypeCacheRecord; + + import spark.events.GridSelectionEvent; + import spark.events.IndexChangeEvent; + import spark.events.TextOperationEvent; + + import flashx.textLayout.operations.SplitParagraphOperation; + + public var CUSTOM_ITEM_SORT_CHARACTER:String = "~"; + + public var PROPERTIES_STATE:String = "properties"; + public var NONE_STATE:String = "none"; + public var BOOLEAN_STATE:String = "boolean"; + public var COLOR_STATE:String = "color"; + public var FORMATS_STATE:String = "formats"; + public var TEXT_STATE:String = "text"; + public var NUMBER_STATE:String = "number"; + public var INT_STATE:String = "int"; + public var UINT_STATE:String = "uint"; + + // LETS GET RID OF SOME OF THESE! + private var fontInfoCollection:XMLListCollection = new XMLListCollection(); + private var allItems:XMLListCollection = new XMLListCollection(); + private var inheritingStylesList:XMLListCollection = new XMLListCollection(); + private var nonInheritingStylesList:XMLListCollection = new XMLListCollection(); + private var objectPropertiesList:XMLListCollection = new XMLListCollection(); + private var _dataProviderProperties:XMLListCollection; + + public var describedType:XML; + + + [Bindable] + public var showSearchBox:Boolean = true; + + [Bindable] + public var showValueBox:Boolean = true; + + [Bindable] + public var showHeader:Boolean = false; + + /** + * Reference to Radiate + * */ + public var radiate:Radiate; + + /** + * Height of the header when not show (to allow resizing of columns) + * */ + public var hiddenHeaderHeight:uint = 0; + + private var _target:Object; + + public function get target():Object { + return _target; + } + + [Bindable] + public function set target(value:Object):void { + + _target = value; + + if (_target) { + clear(); + currentState = NONE_STATE; + populatePropertiesGrid(_target); + } + else { + clear(); + } + } + + + protected function creationCompleteHandler(event:FlexEvent):void { + radiate = Radiate.getInstance(); + + if (!showHeader) { + //propertiesGrid.columnHeaderGroup.visible = showHeader; + propertiesGrid.columnHeaderGroup.height = hiddenHeaderHeight; + } + + radiate.addEventListener(RadiateEvent.TARGET_CHANGE, handleTargetChange, false, 0, true); + radiate.addEventListener(RadiateEvent.PROPERTY_CHANGED, propertyChangeHandler, false, 0, true); + + if (radiate.target) { + target = radiate.target; + } + + } + + protected function handleTargetChange(event:RadiateEvent):void { + target = event.selectedItem; + } + + public function get dataProviderProperties():XMLListCollection { + return _dataProviderProperties; + } + + [Bindable] + public function set dataProviderProperties(value:XMLListCollection):void { + if (_dataProviderProperties) { + _dataProviderProperties = new XMLListCollection(new XMLList()); + } + + /*value.sort = new Sort(); + value.sort.fields = [new SortField("@name", false)]; + value.refresh();*/ + _dataProviderProperties = value; + } + + /** + * Get Name or ID of target object + * */ + public function getName(element:Object):String { + var id:String; + + if (element is UIComponent && element.id != null) { + id = UIComponent(element).id; + } + else if (element.hasOwnProperty("id") && element.id != null) { + id = element.id; + } + else if (element.hasOwnProperty("name") && element.name != null) { + id = element.name; + } + else { + id = ""; + } + return id; + } + + /** + * Populates the datagrid with all the properties that describe type returns for the given object + * */ + public function populatePropertiesGrid(target:Object):void { + var describedTypeRecord:mx.utils.DescribeTypeCacheRecord; + var stylesList:XMLListCollection; + var accessorList:XMLListCollection; + var propertyName:String; + var fontLookup:String; + var fontFamily:String; + var renderingMode:String; + var properties:String; + var inheritingStyles:Object; + var nonInheritingStyles:Object; + var property:String; + var item:XML; + var styleNotDefined:Boolean; + var styleIsColor:Boolean; + + + // TODO: not use xml - use json version + if (target != null) { + //describedType = describeType(target); + var time:int = getTimer(); + /*Radiate.log.info("Get properties on target " + getName(target)); + describedType = ClassUtils.getDescribeType(target); + Radiate.log.info("2 Get properties on target : " + String(getTimer()-time));*/ + describedType = ClassUtils.getDescribeType(target); + //Radiate.log.info("3 Get properties on target : " + String(getTimer()-time)); + accessorList = new XMLListCollection(describedType.accessor); + + // DISABLE UPDATE UNTIL COMPLETE + //allItems.removeAll(); + //allItems.disableAutoUpdate(); + + // ADD ACCESSORS LIST + allItems.addAll(accessorList); + + // if item is an object enumerate + if (describedType.@name=="Object") { + for (property in target) { + item = createXMLItem(property, target[property], null, true, true); + objectPropertiesList.addItem(item); // we could use allItems.addItem(); + } + } + + allItems.addAll(objectPropertiesList); + + /* var blah:Object = getMemberNames(this, true); + blah = getMemberNames(this); + blah = nonInheritingStyles; + blah = styleDeclaration; + blah = styleName; + blah = styleManager.inheritingStyles; + blah = styleManager.qualifiedTypeSelectors; + blah = styleManager.selectors; + blah = styleManager.stylesRoot; + blah = styleManager.typeHierarchyCache; + blah = styleManager.typeSelectorCache; + blah = styleManager.hasAdvancedSelectors(); */ + + if (filterInput) filterInput.text = ""; + + // we check for the text flow property so we can see if fonts are embedded + if (target.hasOwnProperty("textFlow")) { + /* if (target.textFlow.computedFormat) { + fontLookup = target.textFlow.computedFormat.fontLookup; + fontFamily = target.textFlow.computedFormat.fontFamily; + renderingMode = target.textFlow.computedFormat.renderingMode; + fontLookup = "<accessor name='fontLookup' value='" + fontLookup + "'/>"; + fontFamily = "<accessor name='fontFamily' value='" + fontFamily + "'/>"; + renderingMode = "<accessor name='renderingMode' value='" + renderingMode + "'/>"; + properties = fontLookup + fontFamily + renderingMode + propertiesList.toString(); + propertiesList = new XMLList(properties); + } */ + } + + //allItems.addAll(propertiesList); + + + var styles:XMLList = ClassUtils.concatenateMetaDataXMLItems(target, "Style", new XMLList()); + + //describedTypeXML = describeType(target); + stylesList = new XMLListCollection(styles); + + allItems.addAll(stylesList); + + var moduleFactory:IFlexModuleFactory = null; + if (target is IFlexModule) + moduleFactory = target.moduleFactory; + + // attempts to get the values of the properties on the current target + // and add them to the node in string representation + for each (var node:XML in allItems) { + setValueOnNode(node); + } + + // Add in inheriting styles + /*if ("inheritingStyles" in target) { + inheritingStyles = target.inheritingStyles as Object; + + for (property in inheritingStyles) { + item = createXMLItem(property, inheritingStyles[property], null, true, true); + inheritingStylesList.addItem(item); + } + + //trace("Inheriting style count", inheritingStylesList.length); + + //allItems.addAll(inheritingStylesList); + }*/ + + // Add in non inheriting styles - + /*if (target.hasOwnProperty("nonInheritingStyles")) { + nonInheritingStyles = target.nonInheritingStyles as Object; + + for (property in nonInheritingStyles) { + item = createXMLItem(property, nonInheritingStyles[property], null, true, false); + nonInheritingStylesList.addItem(item); + } + + //trace("Non-Inheriting style count", nonInheritingStylesList.length); + + allItems.addAll(nonInheritingStylesList); + }*/ + + + // not using + // create an item for unnamed style + // this floats at the top so we can get the value of a style not listed by describe type + var customItem:XML = createXMLItem(CUSTOM_ITEM_SORT_CHARACTER, "", "String"); + customItem.@search = true; + //allItems.addItem(customItem); + + dataProviderProperties = allItems; + } + else { + dataProviderProperties = new XMLListCollection(); + } + + } + + /** + * Set the value on the node + * */ + public function setValueOnNode(node:XML):void { + var propertyName:String; + var styleNotDefined:Boolean; + var styleIsColor:Boolean; + + propertyName = node.@name; + if (propertyName=="backgroundColor") { + //trace("HELLO"); + } + + if (node.@access != "writeonly") { + + if (propertyName in target) { + + try { + node.@value = target[propertyName]; + //node.@valueIsObject = (target[propertyName] is Object); + } + catch (error:Error) { + node.@value = error.message; + node.@valueError = true; + } + } + // styles + else if (target is IStyleClient) { + styleNotDefined = false; + styleIsColor = false; + var currentVal:Object = target.getStyle(propertyName); + + // Handle situation of turning strings into Boolean values + //if (currentVal is Boolean) + //{ + //if (val is String) val = (value.toLowerCase() == "true"); + //} + // Handle turning standard string representations of colors + // into numberic values + if (propertyName.toLowerCase().indexOf("color") != -1 && + propertyName.toLowerCase().indexOf("colors") == -1) + { + styleIsColor = true; + } + + if (currentVal is Number && styleIsColor) + { + currentVal = StyleManager.getStyleManager(moduleFactory).getColorName(currentVal); + } + + try { + if (target.getStyle(propertyName)===undefined) { + styleNotDefined = true; + node.@styleNotDefined = true; + node.@value = ""; + } + else { + if (styleIsColor) { + node.@value = DisplayObjectUtils.getColorInHex(currentVal as uint, true); + } + else { + node.@value = currentVal; + } + //node.@valueIsObject = (currentVal is Object); + } + } + catch (error:Error) { + node.@value = error.message; + node.@valueError = true; + } + } + + } + } + + /** + * From SetAction + * */ + public function getValue(propName:String):* + { + if (propName in target) + return target[propName]; + else + return target.getStyle(propName); + } + + public function createXMLItem(name:String, value:*, type:String, style:Boolean=false, inheriting:Boolean=false):XML { + var xml:XML = <accessor />; + xml.@name = name; + xml.@style = style; + xml.@inheriting = inheriting; + xml.@access = "readwrite"; + if (type) { + xml.@type = type; + } + else { + xml.@type = InspectorUtils.getValueType(value); + } + xml.@value = value!=null || undefined ? String(value) : ""; + return xml; + } + /* + protected function filterDisplayObjectChangeHandler(item:XML):Boolean { + var itemName:String = item.attribute("name") ? item.attribute("name") : ""; + var value:String = searchPropertyInput.text; + + if (itemName.toLowerCase().indexOf(value) != -1) { + return true; + } + return false; + }*/ + + /** + * Filters the property list + * if we type a period or a space at the end of the word then + * the value and the name have to match exactly (case-insensitive) + * */ + /*protected function filterPropertyChangeHandler(item:XML):Boolean { + var itemName:String = item.attribute("name") ? item.attribute("name") : ""; + var value:String = searchPropertyInput.text; + var valueLength:int = value.length; + var itemNameLength:int = itemName.length; + var valueLowerCase:String = value.toLowerCase(); + var itemNameLowerCase:String = itemName.toLowerCase(); + + // show all items if search is empty + if (valueLength==0) { + return true; + } + + + // show custom item in case of style + if (item.@search=="true") { + + + + // undefined + // at Function/<anonymous>()[E:\dev\4.y\frameworks\projects\framework\src\mx\utils\XMLNotifier.as:93] + // at com.flexcapacitor.views::Properties/filterPropertyChangeHandler()[/Users/monkeypunch/Documents/ProjectsGithub/Radii8/Radii8Library/src/com/flexcapacitor/views/Properties.mxml:331] + // at mx.collections::ListCollectionView/addItemsToView()[E:\dev\4.y\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1089] + // at mx.collections::ListCollectionView/moveItemInView()[E:\dev\4.y\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1594] + // at mx.collections::ListCollectionView/handlePropertyChangeEvents()[E:\dev\4.y\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1421] + // at mx.collections::ListCollectionView/listChangeHandler()[E:\dev\4.y\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1316] + // at flash.events::EventDispatcher/dispatchEventFunction() + // at flash.events::EventDispatcher/dispatchEvent() + // at mx.collections::ListCollectionView/dispatchEvent()[E:\dev\4.y\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1024] + // at mx.collections::ListCollectionView/handlePropertyChangeEvents()[E:\dev\4.y\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1449] + // at mx.collections::ListCollectionView/listChangeHandler()[E:\dev\4.y\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1316] + // at flash.events::EventDispatcher/dispatchEventFunction() + // at flash.events::EventDispatcher/dispatchEvent() + + // at mx.collections::XMLListAdapter/itemUpdateHandler()[E:\dev\4.y\frameworks\projects\framework\src\mx\collections\XMLListAdapter.as:623] + // at mx.collections::XMLListAdapter/itemUpdated()[E:\dev\4.y\frameworks\projects\framework\src\mx\collections\XMLListAdapter.as:366] + // at mx.collections::XMLListAdapter/xmlNotification()[E:\dev\4.y\frameworks\projects\framework\src\mx\collections\XMLListAdapter.as:725] + + // Seems like it's caused by a change > update > change > update loop + + // we have a custom item at the top of the + //filteredPropertiesCollection.disableAutoUpdate(); + item.@name = CUSTOM_ITEM_SORT_CHARACTER + value; + //filteredPropertiesCollection.enableAutoUpdate(); + return true; + } + else { + //filteredPropertiesCollection.disableAutoUpdate(); + } + + // if we type a period or a space at the end of the word then + // the value and the name have to match exactly (case-insensitive) + if (value.lastIndexOf(".")==valueLength-1 || value.lastIndexOf(" ")==valueLength-1) { + if (itemNameLowerCase+"."==valueLowerCase || itemNameLowerCase+" "==valueLowerCase) { + return true; + } + else { + return false; + } + } + + // we filter from any index + if (itemNameLowerCase.indexOf(valueLowerCase) != -1) { + return true; + } + + return false; + }*/ + + /*protected function findPropertyChangeHandler(event:TextOperationEvent):void { + filteredPropertiesCollection.refresh(); + }*/ + + /** + * Attempts to drill into the selected property + * */ + /*protected function gridDoubleClickHandler(event:MouseEvent):void { + // if the user switches applications and the editor is not closed + // we get the text control of the editor. we don't want that so return + if (!(event.target is IDataRenderer)) return; + + var instance:Object = event.currentTarget; + var itemRenderer:IDataRenderer = IDataRenderer(event.target); + var data:XML = itemRenderer.data as XML; + + // this is a check for double click on dataGridColumn + if (data==null) return; + var currentValue:String = String(data.@value); + var propertyName:String = data.@name; + var type:String = String(data.@type); + var something:*; + + if (propertyName in target) { + something = target[propertyName]; + + // if object set new target + if (!ObjectUtil.isSimple(something)) { + target = something; + radiate.dispatchTargetChangeEvent(something); + //InspectorUtils.dispatchTargetChangeEvent(something, this); + } + } + }*/ + /* + protected function propertiesGrid_itemEditEndHandler(oldValue:Object, newValue:Object, editor:DefaultGridItemEditor):void { + throw new Error("Is this used?"); + var instance:Object = editor.column.itemEditor; + if (instance==null) return; + var data:XML = editor.column.grid.selectedItem as XML; //event.itemRenderer.data as XML; + var currentValue:String = String(data[editor.column.dataField]); + var propertyName:String = data.@name; + var searchField:String = data.@search; + var isSearchField:Boolean = searchField=="" || searchField==null ? false : searchField as Boolean;; + var type:String = String(data.@type); + var styleAttribute:String = data.@style; + var isStyle:Boolean = styleAttribute=="" || styleAttribute==null ? false : styleAttribute as Boolean; + var newAssignedValue:*; + var isChanged:Boolean; + + if (isSearchField) { + propertyName = propertyName.replace(CUSTOM_ITEM_SORT_CHARACTER, ""); + isStyle = true; + } + + if (target) { + newAssignedValue = TypeUtils.getTypedValue(newValue, type) + + InspectorUtils.setTargetProperty(target, propertyName, newAssignedValue, type, isStyle); + + } + + callLater(maintainFocus); + }*/ + /* + private function maintainFocus():void { + //propertiesGrid.editedItemPosition = null; + }*/ + + /** + * 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; + + return; // DISABLE FOR NOW + if (filteredPropertiesCollection.length==1) { + item = filteredPropertiesCollection.getItemAt(0) as XML; + if (item && item.nodeName()=="metadata") { + item.@value = target is UIComponent ? UIComponent(target).getStyle(searchText) : ""; + filteredPropertiesCollection.itemUpdated(item, "@value"); + filteredPropertiesCollection.refresh(); + } + } + } + + + /** + * + * */ + public function clear():void { + // on application getting this error: + //RangeError: Index '-1' specified is out of bounds.??? + /*allItems.enableAutoUpdate(); + Radiate.log.info("1Length:"+allItems.length); + allItems.refresh(); + Radiate.log.info("2Length:"+allItems.length); + allItems.sort = null; + Radiate.log.info("3Length:"+allItems.length);*/ + allItems.removeAll(); + allItems.refresh(); + + inheritingStylesList.removeAll(); + nonInheritingStylesList.removeAll(); + objectPropertiesList.removeAll(); + + filterInput.text = ""; + targetValueText.text = ""; + dataProviderProperties = new XMLListCollection(); + } + /* + protected function saveSessionHandler(event:GridItemEditorEvent):void { + //trace("Save session"); + var item:XML = propertiesGrid.dataProvider.getItemAt(event.rowIndex) as XML; + var value:String = String(item.@value); + var property:String = String(item.@name); + + //trace("New Value= ", value); + Radiate.setProperty(target, property, value); + } + + protected function startSessionHandler(event:GridItemEditorEvent):void { + //trace("Start session"); + } + + protected function savingSessionHandler(event:GridItemEditorEvent):void + { + //trace("Saving session"); + } + + protected function startingSessionHandler(event:GridItemEditorEvent):void + { + //trace("Starting session"); + var item:XML = propertiesGrid.dataProvider.getItemAt(event.rowIndex) as XML; + if (String(item.@access).indexOf("write")<0) { + // event.preventDefault(); + // NOTIFY OF READ ONLY + } + }*/ + + protected function propertyChangeHandler(event:RadiateEvent):void + { + // radiate property change event + updateDataGridPropertyValue(event.changes); + //updateSubComponentsValue(); + } + + protected function targetValueText_keyUpHandler(event:KeyboardEvent):void { + + if (event.keyCode==Keyboard.ENTER && !event.shiftKey) { + setTargetValue(); + event.preventDefault(); + } + else if (event.keyCode==Keyboard.ESCAPE) { + var item:XML = propertiesGrid.selectedItem as XML; + var value:String = String(item.@value); + targetValueText.text = value; + event.preventDefault(); + } + } + + /** + * Prevents line breaks + * */ + protected function targetValueText_changingHandler(event:TextOperationEvent):void { + + // prevent line breaks + if(event.operation is SplitParagraphOperation) { + event.preventDefault(); + } + } + + protected function colorChooser_changeHandler(event:Event):void { + setTargetValue(); + } + + /** + * + * */ + protected function propertiesGrid_selectionChangeHandler(event:GridSelectionEvent = null):void { + updateSubComponentsValue(); + } + + protected function formatCombobox_changeHandler(event:IndexChangeEvent):void { + setTargetValue(); + } + + /** + * Update the property value in the datagrid when it changes + * without reloading all the properties. + * */ + public function updateDataGridPropertyValue(changes:Array):void { + var length:int = allItems.length; + var itemList:XMLList; + var propertyName:String; + + if (length>0 && changes.length>0) { + //itemList = allItems.source; + + for each (var node:XML in allItems) { + propertyName = node.@name; + + // TypeError: Error #1034: Type Coercion failed: + // cannot convert mx.states::AddItems@1132558c9 to mx.effects.effectClasses.PropertyChanges. + // for each (var change:PropertyChanges in changes) { + for each (var change:Object in changes) { + + if (change is mx.effects.effectClasses.PropertyChanges) { + var changeObject:Object = change.end; + + for (var property:String in changeObject) { + if (propertyName==property) { + //node.@value = changeObject[property] ? Object(changeObject[property]) : ""; + + // we probably cleared a style + if (changeObject[property]===undefined) { + setValueOnNode(node); + } + else { + setValueOnNode(node); + //node.@value = Object(changeObject[property]).toString(); + filteredPropertiesCollection.itemUpdated(node, "@value"); + filteredPropertiesCollection.refresh(); + } + } + } + } + } + } + } + } + + /** + * Get the value from the datagrid and + * show the correct sub component and + * set it's value. + * */ + public function updateSubComponentsValue():void { + var item:XML = propertiesGrid.selectedItem as XML; + var actualValue:*; + var isStyle:Boolean; + var type:String; + var enumeration:Array; + var format:String; + var propertyObject:MetaData; + var property:String; + var value:String; + var nodename:String; + + if (settingProperties) return; + + if (item) { + nodename = item.name(); + + if (nodename=="metadata") { + isStyle = true; + propertyObject = new StyleMetaData(item, target); + } + else if (nodename=="accessor") { + propertyObject = new AccessorMetaData(item, target); + } + else { + propertyObject = new MetaData(item, target); + } + + + + value = String(propertyObject.value); + property = propertyObject.name; + type = propertyObject.type; + format = propertyObject.format; + enumeration = propertyObject.enumeration; + + + if (type=="Boolean") { + currentState = BOOLEAN_STATE; + booleanEnabledRadioButton.selected = false; + booleanDisabledRadioButton.selected = false; + + if (value=="true") { + booleanEnabledRadioButton.selected = true; + } + else if (value=="false") { + booleanDisabledRadioButton.selected = true; + } + + booleanClearStyleButton.visible = isStyle; + } + else if (format=="Color") { + currentState = COLOR_STATE; + colorChooser.selectedColor = value; + targetValueText.text = value; + clearColorButton.visible = isStyle; + } + else if (enumeration && enumeration.length>0) { + currentState = FORMATS_STATE; + formatsCollection.source = enumeration; + formatCombobox.selectedItem = propertyObject.value; + targetValueText.text = value; + clearFormatButton.visible = isStyle; + } + else if (type=="Number") { + currentState = NUMBER_STATE; + numericStepper.value = propertyObject.value; + + if (!isNaN(propertyObject.minValue)) { + numericStepper.minimum = propertyObject.minValue; + } + else { + numericStepper.minimum = Number(int.MIN_VALUE); + } + if (!isNaN(propertyObject.maxValue)) { + numericStepper.maximum = propertyObject.maxValue; + } + else { + numericStepper.maximum = Number(int.MAX_VALUE); + } + + if (property.indexOf("lpha")!=-1) { + numericStepper.stepSize = .1; + + if (isNaN(propertyObject.minValue)) { + numericStepper.minimum = 0; + } + if (isNaN(propertyObject.maxValue)) { + numericStepper.maximum = 1; + } + } + else { + numericStepper.stepSize = 1; + } + + targetValueText.text = value; + booleanNumberStyleButton.visible = isStyle; + } + else { + actualValue = Radiate.getTypedValue(targetValueText.text, type); + currentState = TEXT_STATE; + targetValueText.text= propertyObject.value; + booleanTextStyleButton.visible = isStyle; + } + + + radiate.dispatchPropertySelectedEvent(property, propertyObject); + } + else { + currentState = NONE_STATE; + } + + } + + + public var settingProperties:Boolean; + + /** + * Set the property to the new value + * */ + public function setTargetValue(clearStyle:Boolean = false):void { + var item:XML = propertiesGrid.selectedItem as XML; + var actualValue:*; + var isStyle:int; + var styleIsColor:Boolean; + var valueSuccessfullyApplied:Boolean; + var propertyObject:MetaData; + var type:String; + var enumeration:Array; + var format:String; + var inherit:Boolean; + var property:String; + var value:String; + var nodename:String; + var access:String; + + if (item) { + nodename = item.name(); + + if (nodename=="metadata") { + isStyle = 1; + propertyObject = new StyleMetaData(item, target); + } + else if (nodename=="accessor") { + propertyObject = new AccessorMetaData(item, target); + access = AccessorMetaData(propertyObject).access; + } + else { + propertyObject = new MetaData(item, target); + } + + // since we try to capture values for history + // ReferenceError: Error #1077: Illegal read of write-only property cacheHeuristic on application. + if (access=="writeonly") { + return; + } + + value = String(propertyObject.value); + property = propertyObject.name; + type = propertyObject.type; + format = propertyObject.format; + enumeration = propertyObject.enumeration; + + /* + var type:Type = Type.forInstance(target); + var metadataItems:Array = type.metadata; + var b:Array = type.getMetadata("Style"); + var metadata:Metadata = Metadata(metadataItems[0]); + var hasFormat:Boolean = metadata.hasArgumentWithKey("type"); + var o:MetadataArgument = metadata.getArgument("type"); + var xc:XML = MetadataUtils.getFromObject(target);*/ + + // BEGIN // COPY CHANGES TO OTHER UPDATE FUNCTION + /*var value:String = String(item.@value); + var property:String = String(item.@name); + var args:XMLList = item.arg; + var metadata:Metadata = new Metadata(name); + var argument:MetadataArgument; + + for each (var arg:XML in args) { + argument = new MetadataArgument(arg.@key, arg.@value); + metadata.arguments.push(argument); + } + + var propertyType:String; + + if (isStyle==1 && metadata.hasArgumentWithKey("type")) { + propertyType = metadata.getArgument("type").value; + } + else { + propertyType = String(item.@type); + } + + var enumeration:Array; + + if (isStyle==1 && metadata.hasArgumentWithKey("enumeration")) { + enumeration = metadata.getArgument("enumeration").value.split(","); + } + + var format:String; + + if (isStyle==1 && metadata.hasArgumentWithKey("format")) { + format = metadata.getArgument("format").value; + }*/ + // END + + //var hasAttribute:Boolean = XML(item).attribute("style").length()>0; + //var valuX:String = String(XML(item).attribute("style")).toString(); + //var valuX2:String = String(item.@style).toString(); + + // this is not a reliable way to compare if the value has changed + // probably remove it since setProperty and setStyle will double check + // if value has really changed + //if (value!=targetValueText.text) { + + if (type=="Boolean") { + if (isStyle) { + actualValue = booleanGroup.selection==null ? undefined : booleanGroup.selection==booleanEnabledRadioButton; + } + else { + actualValue = booleanGroup.selection==booleanEnabledRadioButton; + } + } + // let SetAction convert 0xFF, #ff and red, ReD + else if (format=="Color") { + actualValue = colorChooser.selectedColor; + } + else if (type=="Number") { + actualValue = numericStepper.value; + + if (property.indexOf("lpha")!=-1) {//round down to two places + actualValue = int(actualValue*100)/100; + } + } + else if (type=="String" && enumeration && enumeration.length>0) { + actualValue = formatCombobox.selectedItem; + } + else { + actualValue = Radiate.getTypedValue(targetValueText.text, type); + } + + + settingProperties = true; + + if (isStyle) { + if (clearStyle) { + valueSuccessfullyApplied = Radiate.clearStyle(target, property); + } + else { + valueSuccessfullyApplied = Radiate.setStyle(target, property, actualValue); + } + } + else { + valueSuccessfullyApplied = Radiate.setProperty(target, property, actualValue); + } + } + + settingProperties = false; + } + + /** + * Set the property to the new value + * */ + public function getEditorType(item:XML):String { + var actualValue:*; + var isStyle:Boolean; + var type:String; + var enumeration:Array; + var format:String; + var propertyObject:MetaData; + var property:String; + var value:String; + var nodename:String; + + if (item) { + nodename = item.name(); + + if (nodename=="metadata") { + isStyle = true; + propertyObject = new StyleMetaData(item, target); + } + else if (nodename=="accessor") { + propertyObject = new AccessorMetaData(item, target); + } + else { + propertyObject = new MetaData(item, target); + } + + + + value = String(propertyObject.value); + property = propertyObject.name; + type = propertyObject.type; + format = propertyObject.format; + enumeration = propertyObject.enumeration; + + + if (type=="Boolean") { + return BOOLEAN_STATE; + } + else if (format=="Color") { + return COLOR_STATE; + } + else if (enumeration && enumeration.length>0) { + return FORMATS_STATE; + } + else if (type=="Number") { + return NUMBER_STATE; + } + else { + return TEXT_STATE; + } + } + + return NONE_STATE; + } + + protected function clearStyleButton_clickHandler(event:MouseEvent):void { + setTargetValue(true); + } + + /** + * 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); + } + } + } + + /** + * Move from properties grid to search text input on up arrow key + * */ + protected function propertiesGrid_keyUpHandler(event:KeyboardEvent):void { + /* + if (event.keyCode==Keyboard.UP) { + if (propertiesGrid.selectedIndex ==0 || + filteredPropertiesCollection.length==0) { + filterInput.setFocus(); + //filterInput.selectRange(filterInput.text.length,filterInput.text.length); + } + } + else if (event.keyCode==Keyboard.DOWN) { + if (propertiesGrid.selectedIndex==filteredPropertiesCollection.length-1) { + + if (!moveDownOnNextDownArrow) { + moveDownOnNextDownArrow = true; + return; + } + + moveDownOnNextDownArrow = false; + focusManager.setFocus(focusManager.getNextFocusManagerComponent()); + + //filterInput.selectRange(filterInput.text.length,filterInput.text.length); + } + }*/ + } + + /** + * + * */ + protected var moveDownOnNextDownArrow:Boolean; + + /** + * Updated when the boolean change happens + * */ + protected function booleanGroup_changeHandler(event:Event):void { + setTargetValue(); + } + + /** + * + * */ + protected function numericStepper_changeHandler(event:Event):void { + setTargetValue(); + } + + /** + * Format numeric stepper + * Trim down to 2 decimal places. + * */ + public function formatNumericStepper(value:Number):String { + + return String(int(value*100)/100); + } + + protected function changeStatesButton_clickHandler(event:MouseEvent):void { + if (currentState!=PROPERTIES_STATE) { + currentState = PROPERTIES_STATE; + } + else { + currentState = NONE_STATE; + } + } + + public function labelFunction(data:Object, column:GridColumn):String { + StringUtils.prettifyCamelCase(data.@name); + return ""; + } + + public function propertiesGridItemRendererFunction(item:Object, column:GridColumn):IFactory { + // Create a Class Factory variable + var rendererFactory:ClassFactory; + var type:Class; + var editorState:String = getEditorType(XML(item)); + + switch (editorState) { + case BOOLEAN_STATE: + type = BooleanRenderer; + break; + case COLOR_STATE: + type = ColorPickerRenderer; + break; + case FORMATS_STATE: + type = ComboBoxRenderer; + break; + case NUMBER_STATE: + type = NumberRenderer; + break; + case TEXT_STATE: + type = com.flexcapacitor.views.renderers.TextRenderer; + break; + default: + type = com.flexcapacitor.views.renderers.TextRenderer; + } + + rendererFactory = new ClassFactory(type); + //rendererFactory.properties = { MyBackgroundColor: varDefaultBackgroundColor, MyForegroundColor: varDefaultForegroundColor }; + + return rendererFactory; + } + + ]]> + </fx:Script> + + + <fx:Declarations> + + <s:NumberFormatter id="formatter" + useGrouping="false"/> + + <s:ArrayCollection id="filteredPropertiesCollection" + list="{dataProviderProperties}"/> + + <s:ArrayCollection id="formatsCollection"/> + + <fx:Array id="filterArray"> + <fx:String>accentColor</fx:String> + <fx:String>visible</fx:String> + </fx:Array> + + <!-- SORT BY NAME --> + <handlers:EventHandler eventName="creationComplete" > + <collections:SortCollection target="{filteredPropertiesCollection}" + fields="{['@name']}" /> + </handlers:EventHandler> + + <!-- FILTER BY NAME --> + <handlers:EventHandler eventName="change" + targets="{[filterInput,showAllItemsOnEmpty,caseSensitive,searchAtStart]}" + > + <collections:FilterCollection target="{filteredPropertiesCollection}" + source="{filterInput}" + sourcePropertyName="text" + fieldName="@name" + showAllItemsOnEmpty="{showAllItemsOnEmpty.selected}" + caseSensitive="{caseSensitive.selected}" + searchAtStart="{searchAtStart.selected}" + /> + </handlers:EventHandler> + + <s:RadioButtonGroup id="booleanGroup" change="booleanGroup_changeHandler(event)"/> + </fx:Declarations> + + <s:states> + <s:State name="none"/> + <s:State name="number"/> + <s:State name="boolean"/> + <s:State name="int"/> + <s:State name="text"/> + <s:State name="color"/> + <s:State name="formats"/> + <s:State name="properties"/> + <s:State name="dynamicInspector"/> + </s:states> + + + + <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%" + excludeFrom="properties" + > + + <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: {filteredPropertiesCollection.length}"/> + </s:HGroup> + </s:Group> + + <!-- PROPERTIES GRID --> + <c:DataGrid id="propertiesGrid" + borderAlpha="0.2" + height="100%" + width="100%" + minWidth="80" + minHeight="48" + rowHeight="26" + variableRowHeight="false" + dataProvider="{filteredPropertiesCollection}" + selectionChange="propertiesGrid_selectionChangeHandler(event)" + click="propertiesGrid_selectionChangeHandler()" + keyUp="propertiesGrid_keyUpHandler(event)" + excludeFrom="properties" + > +<!-- gridItemEditorSessionStart="startSessionHandler(event)" + gridItemEditorSessionSave="saveSessionHandler(event)" + gridItemEditorSessionSaving="savingSessionHandler(event)" + gridItemEditorSessionStarting="startingSessionHandler(event)"--> + <!--<s:layout> + <s:VerticalLayout rowHeight="22" /> + </s:layout>--> + <c:columns> + <s:ArrayCollection> + + <s:GridColumn dataField="@type" + width="14" + editable="false" + resizable="true" + headerText="PROPERTY"> + <s:itemRenderer> + <fx:Component> + <s:GridItemRenderer minHeight="14" > + <s:BitmapImage top="8" left="3" source="{Radii8LibraryAssets.propertyIcon}"/> + </s:GridItemRenderer> + </fx:Component> + </s:itemRenderer> + </s:GridColumn> + + <s:GridColumn dataField="@name" + minWidth="50" + editable="false" + resizable="true" + headerText="PROPERTY" > + <s:itemRenderer> + <fx:Component> + <s:GridItemRenderer minHeight="14"> + <s:Label id="labelDisplay" + verticalCenter="1" left="0" right="0" top="0" bottom="0" + fontSize="12" + paddingTop="3" + paddingBottom="3" + paddingLeft="3" + paddingRight="3" + textAlign="start" + verticalAlign="middle" + width="100%" + maxDisplayedLines="1" + showTruncationTip="true"/> + </s:GridItemRenderer> + </fx:Component> + </s:itemRenderer> + </s:GridColumn> + + <s:GridColumn dataField="@value" + minWidth="50" + editable="false" + resizable="true" + headerText="VALUE" + itemRenderer="com.flexcapacitor.views.renderers.PropertiesGridValuesRenderer"> + </s:GridColumn> + + <!--<s:GridColumn headerText="" + minWidth="30" + width="30" + editable="false" + labelFunction="{function(data:Object, column:GridColumn):String{return'...';}}"> + </s:GridColumn>--> + + + <!--<s:GridColumn width="50" + dataField="@type" editable="false" + headerText="type"/> + <s:GridColumn width="35" + dataField="@style" editable="false" + headerText="Style"/> + <s:GridColumn width="35" + dataField="@inheriting" editable="false" + headerText="Inheriting"/>--> + + </s:ArrayCollection> + </c:columns> + </c:DataGrid> + + + + <!-- FORM --> + <!-- PROPERTIES LIST --> + <c:DataGrid id="propertiesList" + borderAlpha="0" + height="100%" + width="100%" + minWidth="80" + minHeight="48" + rowHeight="26" + variableRowHeight="false" + selectionColor="#ffffff" + rollOverColor="#ffffff" + dataProvider="{filteredPropertiesCollection}" + includeIn="properties" + > + <c:columns> + <s:ArrayCollection> + + <s:GridColumn dataField="@name" + minWidth="50" + editable="false" + resizable="true" + headerText="PROPERTY"> + <s:itemRenderer> + <fx:Component> + <s:GridItemRenderer minHeight="14"> + <s:Label id="labelDisplay" + verticalCenter="1" left="0" right="0" top="0" bottom="0" + fontSize="12" + paddingTop="3" + paddingBottom="3" + paddingLeft="3" + paddingRight="12" + textAlign="right" + verticalAlign="middle" + width="100%" + maxDisplayedLines="1" + showTruncationTip="true"/> + </s:GridItemRenderer> + </fx:Component> + </s:itemRenderer> + </s:GridColumn> + + <s:GridColumn dataField="@value" + minWidth="50" + editable="false" + resizable="true" + headerText="VALUE" + itemRendererFunction="propertiesGridItemRendererFunction" + itemRenderer="com.flexcapacitor.views.renderers.ColorPickerRenderer" + > +<!-- labelFunction="labelFunction"--> + + </s:GridColumn> + <s:GridColumn minWidth="10" + editable="false" + resizable="false" + headerText="" + > + + </s:GridColumn> + + <!--<s:GridColumn headerText="" + minWidth="30" + width="30" + editable="false" + labelFunction="{function(data:Object, column:GridColumn):String{return'...';}}"> + </s:GridColumn>--> + + + <!--<s:GridColumn width="50" + dataField="@type" editable="false" + headerText="type"/> + <s:GridColumn width="35" + dataField="@style" editable="false" + headerText="Style"/> + <s:GridColumn width="35" + dataField="@inheriting" editable="false" + headerText="Inheriting"/>--> + + </s:ArrayCollection> + </c:columns> + </c:DataGrid> + + + <s:Group height="28" minHeight="28" width="100%" + clipAndEnableScrolling="true"> + + <!-- TEXT OPTION --> + <s:Group width="100%" + height="100%" + includeIn="text" + itemCreationPolicy="immediate" + > + <s:TextArea id="targetValueText" + width="100%" + height="100%" + borderAlpha="0.2" + skinClass="spark.skins.spark.TextAreaSkin" + keyUp="targetValueText_keyUpHandler(event)" + changing="targetValueText_changingHandler(event)" + > + </s:TextArea> + + <s:Button id="booleanTextStyleButton" + skinClass="com.flexcapacitor.skins.ClearButton" + click="clearStyleButton_clickHandler(event)" + right="0" + verticalCenter="0"/> + </s:Group> + + + <!-- COLOR OPTION --> + <s:Group width="100%" + height="24" + includeIn="color" + itemCreationPolicy="immediate" + > + <components:ColorChooser id="colorChooser" returnType="hexidecimalHash" + change="colorChooser_changeHandler(event)"/> + + <s:Button id="clearColorButton" + skinClass="com.flexcapacitor.skins.ClearButton" + click="clearStyleButton_clickHandler(event)" + right="0" + verticalCenter="0"/> + </s:Group> + + + <!-- CHOICES OPTION --> + <s:HGroup width="100%" + height="24" + includeIn="formats" + itemCreationPolicy="immediate" + > + <s:DropDownList id="formatCombobox" + width="100%" + change="formatCombobox_changeHandler(event)" + dataProvider="{formatsCollection}"/> + <s:Button id="clearFormatButton" + skinClass="com.flexcapacitor.skins.ClearButton" + click="clearStyleButton_clickHandler(event)" + right="0" + verticalCenter="0"/> + </s:HGroup> + + + <!-- NUMBERS --> + <s:HGroup width="100%" + height="24" + includeIn="number" + itemCreationPolicy="immediate" + > + <s:NumericStepper id="numericStepper" + width="100%" + valueFormatFunction="formatNumericStepper" + change="numericStepper_changeHandler(event)"/> + <s:Button id="booleanNumberStyleButton" + skinClass="com.flexcapacitor.skins.ClearButton" + click="clearStyleButton_clickHandler(event)" + right="0" + verticalCenter="0" + /> + </s:HGroup> + + + <!-- BOOLEAN OPTIONS --> + <s:HGroup width="100%" + height="24" + minHeight="24" + includeIn="boolean" + itemCreationPolicy="immediate" + verticalAlign="middle" + > + + <s:RadioButton id="booleanEnabledRadioButton" + label="True" + group="{booleanGroup}" + /> + <s:RadioButton id="booleanDisabledRadioButton" + label="False" + group="{booleanGroup}" + /> + + <s:Spacer width="100%"/> + + <s:Button id="booleanClearStyleButton" + skinClass="com.flexcapacitor.skins.ClearButton" + click="clearStyleButton_clickHandler(event)" + /> + </s:HGroup> + </s:Group> + + </mx:VDividedBox> + +</s:Group>
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/PropertyInspector2.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/panels/PropertyInspector2.mxml b/Radii8Library/src/com/flexcapacitor/views/panels/PropertyInspector2.mxml new file mode 100644 index 0000000..637f849 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/panels/PropertyInspector2.mxml @@ -0,0 +1,76 @@ +<?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" + minWidth="200" + minHeight="100" + xmlns:c="com.flexcapacitor.controls.*" + creationComplete="group1_creationCompleteHandler(event)"> + + + <!-- + + --> + <fx:Script> + <![CDATA[ + import com.flexcapacitor.controller.Radiate; + import com.flexcapacitor.events.RadiateEvent; + + import mx.events.FlexEvent; + + /** + * Reference to Radiate + * */ + public var radiate:Radiate; + + private var _target:Object; + + public function get target():Object { + return _target; + } + + [Bindable] + public function set target(value:Object):void { + + _target = value; + + if (_target) { + + } + else { + + } + } + + protected function group1_creationCompleteHandler(event:FlexEvent):void { + radiate = Radiate.getInstance(); + radiate.addEventListener(RadiateEvent.TOOL_CHANGE, handleTargetChange); + } + + protected function handleTargetChange(event:RadiateEvent):void { + target = event.selectedItem; + } + + ]]> + </fx:Script> + + +</s:Group> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/panels/States.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/panels/States.mxml b/Radii8Library/src/com/flexcapacitor/views/panels/States.mxml new file mode 100644 index 0000000..b9e618e --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/panels/States.mxml @@ -0,0 +1,293 @@ +<?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" + width="400" height="250" + creationComplete="group1_creationCompleteHandler(event)" + > + + <!--- + + // TypeError: Error #1034: Type Coercion failed: cannot convert mx.states::State@13223d179 to mx.states.State. + --> + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.controller.Radiate; + import com.flexcapacitor.events.RadiateEvent; + import com.flexcapacitor.utils.ClassUtils; + import com.flexcapacitor.utils.DisplayObjectUtils; + + import mx.collections.ArrayCollection; + import mx.events.FlexEvent; + import mx.states.AddItems; + import mx.states.SetProperty; + + import spark.components.List; + import spark.events.IndexChangeEvent; + import spark.layouts.VerticalLayout; + + private var radiate:Radiate = Radiate.instance; + + private var target:Object; + + // TypeError: Error #1034: Type Coercion failed: cannot convert mx.states::State@13223d179 to mx.states.State. + private var selectedState:Object; + private var selectedStateName:String; + private var usingSkinStates:Boolean; + private var statesFound:Boolean; + private var componentStates:Array; + + [Bindable] + public var statesCollection:ArrayCollection; + [Bindable] + public var overridesCollection:ArrayCollection; + [Bindable] + public var groupsCollection:ArrayCollection; + + protected function group1_creationCompleteHandler(event:FlexEvent):void { + radiate.addEventListener(RadiateEvent.TARGET_CHANGE, targetChangeHandler); + + if (radiate.target) { + updateTarget(radiate.target); + } + } + + protected function targetChangeHandler(event:RadiateEvent):void { + updateTarget(event.selectedItem); + + } + + protected function updateTarget(selectedItem:Object):void { + // TypeError: Error #1034: Type Coercion failed: cannot convert mx.states::State@13223d179 to mx.states.State. + // changing to Object type + var state:Object; + + //if (target==selectedItem) return; + + target = selectedItem; + + if (!statesCollection) { + statesCollection = new ArrayCollection(); + overridesCollection = new ArrayCollection(); + groupsCollection = new ArrayCollection(); + } + + statesCollection.source = []; + overridesCollection.source = []; + groupsCollection.source = []; + selectedState = null; + selectedStateName = ""; + componentStates = []; + usingSkinStates = false; + statesFound = false; + + if (!target) { + return; + } + + if ("states" in target) { + componentStates = target.states as Array; + if ("currentState" in target) { + selectedStateName = target.currentState; + } + } + + if ((!componentStates || componentStates.length==0) && "skin" in target && target.skin) { + componentStates = target.skin.states as Array; + + if ("currentState" in target.skin) { + selectedStateName = target.skin.currentState; + } + usingSkinStates = true; + } + + if (componentStates.length>0) { + statesFound = true; + statesCollection.source = componentStates; + + // TypeError: Error #1034: Type Coercion failed: cannot convert mx.states::State@13223d179 to mx.states.State. + for each (state in componentStates) { + if (state.name == selectedStateName) { + selectedState = state; + break; + } + } + + list.selectedItem = selectedState; + + updateState(selectedState); + } + else { + + statesFound = false; + statesCollection.source = []; + + } + + if (statesCollection.length) { + list.validateNow(); + + if (VerticalLayout(list.layout).rowHeight) { + list.height = VerticalLayout(list.layout).rowHeight * statesCollection.length; + } + else { + list.height = 80; + } + } + else { + list.height = 30; + } + } + + + protected function list_changeHandler(event:IndexChangeEvent):void { + var state:Object = list.selectedItem; + + if (statesFound && state) { + updateState(state); + //dividerGroup.visible = true; + } + else { + //dividerGroup.visible = false; + } + + } + + public function updateState(state:Object):void { + + if (usingSkinStates) { + if ("hasState" in target.skin && target.skin.hasState(state.name)) { + Radiate.setProperty(target.skin, "currentState", state.name); + //target.skin.currentState = state.name; + } + } + else { + // ArgumentError: Undefined state 'normal'. + if ("hasState" in target && target.hasState(state.name)) { + Radiate.setProperty(target, "currentState", state.name); + //target.currentState = state.name; + } + } + + overridesCollection.source = state.overrides; + groupsCollection.source = state.stateGroups; + } + + public function groupsLabelFunction(item:Object):String { + var item2:Object = item; + + return ""; + } + + public function overridesLabelFunction(item:Object):String { + var addItems:AddItems = item as AddItems; + var setProperty:SetProperty = item as SetProperty; + var currentTarget:String; + var label:String; + + if (addItems) { + label = "Add " + ClassUtils.getClassNameOrID(addItems.items) + " to " + ClassUtils.getClassNameOrID(addItems.destination); + } + else if (item is SetProperty) { + var value:* = setProperty.value; + currentTarget = setProperty.target ? ClassUtils.getClassNameOrID(setProperty.target) + "." : ""; + if (setProperty.name.toLowerCase().indexOf("color")!=-1) { + value = DisplayObjectUtils.getColorInHex(setProperty.value, true); + } + label = "Set " + currentTarget + setProperty.name + " to " + value; + } + else { + label = ClassUtils.getClassName(item); + } + + return label; + } + ]]> + </fx:Script> + + <s:VGroup width="100%" height="100%" paddingLeft="6" paddingRight="6" paddingBottom="6"> + <s:Label text="No states defined" + color="#585858" + alpha="1" + fontStyle="italic" + backgroundColor="#ffffff" + backgroundAlpha="1" + visible="{statesCollection.length==0}" + includeInLayout="{statesCollection.length==0}" + /> + + <s:List id="list" + minHeight="20" + width="100%" + labelField="name" + borderAlpha=".2" + rollOverColor="#ffffff" + selectionColor="#d8d8d8" + visible="{statesCollection.length!=0}" + dataProvider="{statesCollection}" + change="list_changeHandler(event);" + verticalScrollPolicy="off" + > + </s:List> + + <s:Label text="OVERRIDES" + color="#585858" + alpha="1" + width="100%" + styleName="formItem" + /> + + <s:Scroller width="100%" height="100%" > + <s:Group width="100%" > + + <s:Label text="No overrides defined" + color="#585858" + alpha="1" + fontStyle="italic" + backgroundColor="#ffffff" + backgroundAlpha="1" + visible="{statesCollection.length==0}" + includeInLayout="{statesCollection.length==0}" + /> + + <s:List id="overrides" + minHeight="40" + height="100%" + width="100%" + borderAlpha=".2" + rollOverColor="#ffffff" + selectionColor="#d8d8d8" + visible="{overridesCollection.length!=0}" + labelFunction="overridesLabelFunction" + dataProvider="{overridesCollection}" + change="list_changeHandler(event)" + > + </s:List> + </s:Group> + </s:Scroller> + + </s:VGroup> + + + + +</s:Group> http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/renderers/BooleanRenderer.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/renderers/BooleanRenderer.mxml b/Radii8Library/src/com/flexcapacitor/views/renderers/BooleanRenderer.mxml new file mode 100644 index 0000000..f08c9fb --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/renderers/BooleanRenderer.mxml @@ -0,0 +1,59 @@ +<?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. + +--> +<r:PropertiesGridRendererBase 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.components.*" + xmlns:r="com.flexcapacitor.views.renderers.*" + + clipAndEnableScrolling="true"> + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.skins.ClearButton; + + + ]]> + </fx:Script> + + <fx:Declarations> + <s:RadioButtonGroup id="booleanGroup" change="setTargetValue()"/> + </fx:Declarations> + + <r:layout> + <s:HorizontalLayout /> + </r:layout> + + <s:RadioButton id="booleanEnabledRadioButton" + label="True" + groupName="booleanGroup" + /> + <s:RadioButton id="booleanDisabledRadioButton" + label="False" + groupName="booleanGroup" + /> + + <s:Spacer width="100%"/> + + <s:Button id="clearStyleButton" + skinClass="com.flexcapacitor.skins.ClearButton" + click="setTargetValue(true)" + /> +</r:PropertiesGridRendererBase> http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/renderers/ColorPickerRenderer.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/renderers/ColorPickerRenderer.mxml b/Radii8Library/src/com/flexcapacitor/views/renderers/ColorPickerRenderer.mxml new file mode 100644 index 0000000..eb81ce4 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/renderers/ColorPickerRenderer.mxml @@ -0,0 +1,56 @@ +<?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. + +--> +<r:PropertiesGridRendererBase 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.components.*" + xmlns:r="com.flexcapacitor.views.renderers.*" + + clipAndEnableScrolling="true"> + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.skins.ClearButton; + + + ]]> + </fx:Script> + + <fx:Declarations> + <fx:Boolean id="includeCopyIcon"/> + <fx:Boolean id="includeTextInput"/> + </fx:Declarations> + + <r:layout> + <s:HorizontalLayout /> + </r:layout> + + <c:ColorChooser id="colorChooser" left="0" top="0" right="0" bottom="0" + returnType="hexidecimalHash" + change="setTargetValue()" + includeTextInput="{includeTextInput}" + includeCopyIcon="{includeCopyIcon}"/> + <s:Button id="clearStyleButton" + skinClass="com.flexcapacitor.skins.ClearButton" + click="setTargetValue(true)" + right="0" + verticalCenter="0"/> + +</r:PropertiesGridRendererBase> http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/renderers/ComboBoxRenderer.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/renderers/ComboBoxRenderer.mxml b/Radii8Library/src/com/flexcapacitor/views/renderers/ComboBoxRenderer.mxml new file mode 100644 index 0000000..02254e6 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/renderers/ComboBoxRenderer.mxml @@ -0,0 +1,48 @@ +<?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. + +--> +<r:PropertiesGridRendererBase 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.components.*" + xmlns:r="com.flexcapacitor.views.renderers.*" + + clipAndEnableScrolling="true"> + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.skins.ClearButton; + + ]]> + </fx:Script> + + <r:layout> + <s:HorizontalLayout /> + </r:layout> + + <s:ComboBox id="formatCombobox" + width="100%" + change="setTargetValue()" + dataProvider="{formatsCollection}"/> + <s:Button id="clearStyleButton" + skinClass="com.flexcapacitor.skins.ClearButton" + click="setTargetValue(true);" + right="0" + verticalCenter="0"/> +</r:PropertiesGridRendererBase> http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/renderers/DropDownListRenderer.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/renderers/DropDownListRenderer.mxml b/Radii8Library/src/com/flexcapacitor/views/renderers/DropDownListRenderer.mxml new file mode 100644 index 0000000..7004da6 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/renderers/DropDownListRenderer.mxml @@ -0,0 +1,48 @@ +<?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. + +--> +<r:PropertiesGridRendererBase 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.components.*" + xmlns:r="com.flexcapacitor.views.renderers.*" + + clipAndEnableScrolling="true"> + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.skins.ClearButton; + + ]]> + </fx:Script> + + <r:layout> + <s:HorizontalLayout /> + </r:layout> + + <s:DropDownList id="formatDropDownList" + width="100%" + change="setTargetValue()" + dataProvider="{formatsCollection}"/> + <s:Button id="clearStyleButton" + skinClass="com.flexcapacitor.skins.ClearButton" + click="setTargetValue(true);" + right="0" + verticalCenter="0"/> +</r:PropertiesGridRendererBase> http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/renderers/EditableDocumentRenderer.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/renderers/EditableDocumentRenderer.mxml b/Radii8Library/src/com/flexcapacitor/views/renderers/EditableDocumentRenderer.mxml new file mode 100644 index 0000000..acb05e1 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/renderers/EditableDocumentRenderer.mxml @@ -0,0 +1,180 @@ +<?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:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/halo" + doubleClickEnabled="true" + doubleClick="itemrenderer1_doubleClickHandler(event)" + autoDrawBackground="true" + height="25"> + + <fx:Metadata> + [HostComponent("spark.components.List")] + </fx:Metadata> + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.controller.Radiate; + import com.flexcapacitor.model.DocumentData; + import com.flexcapacitor.model.IDocument; + + import spark.components.List; + import spark.components.supportClasses.ListBase; + + public var iDocument:IDocument; + + /** + * + * */ + override public function set data(value:Object):void { + super.data = value; + + iDocument = value ? IDocument(value) : null; + + if (iDocument && labelDisplay) { + labelDisplay.text = iDocument.name; + } + + } + + + override public function setCurrentState(stateName:String, playTransition:Boolean=true):void { + super.setCurrentState(stateName, playTransition); + } + + protected function textInputChangeHandler():void { + //this.data = textInput.text; + + //dispatch the data update event + var list:ListBase = this.owner as ListBase; + + if (data && iDocument) { + var oldName:String = iDocument.name; + var newName:String = textInput.text; + Radiate.getInstance().renameDocument(iDocument, newName); + list.dataProvider.itemUpdated(iDocument, "name", oldName, newName); + currentState = "normal"; + } + } + + protected function itemrenderer1_doubleClickHandler(event:MouseEvent):void { + currentState = "edit"; + textInput.text = labelDisplay.text; + } + + override protected function getCurrentRendererState():String { + // if in edit state don't change unless + if (currentState=="edit") return "edit"; + + return super.getCurrentRendererState(); + } + + protected function textInput_focusOutHandler(event:FocusEvent):void { + textInputChangeHandler(); + currentState = "normal"; + } + + protected function openIcon_clickHandler(event:MouseEvent):void { + Radiate.getInstance().openDocument(this.data as IDocument); + } + + ]]> + </fx:Script> + + <s:states> + <s:State name="normal" /> + <s:State name="hovered" /> + <s:State name="selected" /> + <s:State name="disabled" /> + <s:State name="edit" enterState="textInput.setFocus()"/> + </s:states> + + <!--<s:Rect height="100%" width="100%"> + <s:fill> + <s:SolidColor color="0xEEFFFF" + alpha="0" + alpha.hovered="0.1" + alpha.selected="0.4" /> + </s:fill> + </s:Rect>--> + + <s:BitmapImage id="icon" + source="{Radii8LibraryAssets.documentIcon}" + left="5" + top="5" + > + </s:BitmapImage> + + + <s:BitmapImage id="saveIcon" + source="{Radii8LibraryAssets.save}" + right="5" + top="5" + visible="{data && (DocumentData(data).saveInProgress || DocumentData(data).openInProgress)}" + > + </s:BitmapImage> + + <!--click event is not getting dispatched <s:Image id="openIcon" + source="{Radii8LibraryAssets.openFolder}" + right="5" + top="5" + visible="{data && !(DocumentData(data).isOpen && !DocumentData(data).openInProgress)}" + click="openIcon_clickHandler(event)" + > + </s:Image>--> + + + <s:Label id="labelDisplay" + top="3" + left="18" + paddingLeft="4" + height="100%" + width="100%" + verticalAlign="middle" + itemCreationPolicy="immediate" + includeIn="hovered, normal, selected"/> + + <!--<s:Label id="isChangedLabel" + top="3" + left="16" + text="*" + verticalAlign="middle" + itemCreationPolicy="immediate" + includeIn="hovered, normal, selected" + visible="{(data as DocumentData).isChanged}"/>--> + + <s:Label id="isChangedLabel2" + bottom="0" + left="0" + text=" " + height="100%" + width="4" + backgroundColor="#989898" + backgroundAlpha="1" + visible="{data && DocumentData(data).isChanged}"/> + + <s:TextInput id="textInput" + left="18" + includeIn="edit" + focusAlpha="0" + enter="textInputChangeHandler()" + focusOut="textInput_focusOutHandler(event)" + width="100%" height="100%"/> +</s:ItemRenderer> http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/renderers/EditableProjectRenderer.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/renderers/EditableProjectRenderer.mxml b/Radii8Library/src/com/flexcapacitor/views/renderers/EditableProjectRenderer.mxml new file mode 100644 index 0000000..f2896e1 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/renderers/EditableProjectRenderer.mxml @@ -0,0 +1,150 @@ +<?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:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/halo" + + doubleClickEnabled="true" + doubleClick="itemrenderer1_doubleClickHandler(event)" + autoDrawBackground="true" + useHandCursor="true" + buttonMode="true" + height="22" + > + + <fx:Metadata> + [HostComponent("spark.components.List")] + </fx:Metadata> + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.model.IProject; + import com.flexcapacitor.model.DocumentData; + + import spark.components.List; + import spark.components.supportClasses.ListBase; + + /** + * + * */ + override public function set data(value:Object):void { + super.data = value; + var project:IProject = value ? IProject(value) : null; + + if (project && labelDisplay) { + labelDisplay.text = project.name; + } + + } + + + protected function dataChangeHandler():void { + //this.data = textInput.text; + + //dispatch the data update event + var list:ListBase = this.owner as ListBase; + var project:IProject = IProject(data); + project.name = textInput.text; + list.dataProvider.itemUpdated(project, "name", project.name, textInput.text); + currentState = "normal"; + project.checkProjectHasChanged(); + } + + protected function itemrenderer1_doubleClickHandler(event:MouseEvent):void { + currentState = "edit"; + textInput.text = labelDisplay.text; + } + + override protected function getCurrentRendererState():String { + // if in edit state don't change unless + if (currentState=="edit") return "edit"; + + return super.getCurrentRendererState(); + } + + protected function textInput_focusOutHandler(event:FocusEvent):void { + dataChangeHandler(); + currentState = "normal"; + } + + ]]> + </fx:Script> + + <s:states> + <s:State name="normal" /> + <s:State name="hovered" /> + <s:State name="selected" /> + <s:State name="disabled" /> + <s:State name="edit" enterState="textInput.setFocus()"/> + </s:states> + + <!--<s:Rect height="100%" width="100%"> + <s:fill> + <s:SolidColor color="0xEEFFFF" + alpha="0" + alpha.hovered="0.1" + alpha.selected="0.4" /> + </s:fill> + </s:Rect>--> + + <s:BitmapImage id="icon" + source="{data && DocumentData(data).isOpen ? Radii8LibraryAssets.openFolder : Radii8LibraryAssets.projectIcon}" + top="4" + left="5" + > + + </s:BitmapImage> + + <s:BitmapImage id="saveIcon" + source="{Radii8LibraryAssets.save}" + right="5" + top="2" + visible="{data && (DocumentData(data).saveInProgress || DocumentData(data).openInProgress)}" + > + </s:BitmapImage> + + <s:Label id="labelDisplay" + height="100%" + width="100%" + left="20" + top="3" + verticalAlign="middle" + itemCreationPolicy="immediate" + paddingLeft="5" + includeIn="hovered, normal, selected"/> + + <s:Label id="isChangedLabel2" + bottom="0" + left="0" + text=" " + height="100%" + width="4" + backgroundColor="#989898" + backgroundAlpha="1" + visible="{data && DocumentData(data).isChanged}"/> + + <s:TextInput id="textInput" + left="20" + includeIn="edit" + focusAlpha="0" + enter="dataChangeHandler()" + focusOut="textInput_focusOutHandler(event)" + width="100%" height="100%"/> +</s:ItemRenderer> http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/renderers/HistoryItemRenderer.mxml ---------------------------------------------------------------------- diff --git a/Radii8Library/src/com/flexcapacitor/views/renderers/HistoryItemRenderer.mxml b/Radii8Library/src/com/flexcapacitor/views/renderers/HistoryItemRenderer.mxml new file mode 100644 index 0000000..e909581 --- /dev/null +++ b/Radii8Library/src/com/flexcapacitor/views/renderers/HistoryItemRenderer.mxml @@ -0,0 +1,93 @@ +<?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:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/mx" + xmlns:controls="com.flexcapacitor.controls.*" + width="100%" height="18" + autoDrawBackground="false" + typographicCase="capsToSmallCaps" + useHandCursor="true" + buttonMode="true" + > + + <fx:Script> + <![CDATA[ + import com.flexcapacitor.events.HistoryEvent; + + public var historyItem:HistoryEvent; + + override public function set data(value:Object):void { + super.data = value; + + if (value) { + historyItem = value as HistoryEvent; + + //rowGroup.enabled = !historyItem.reversed; + //Radiate.log.info("updating row " + itemIndex + " :" + label + " . Enabled " + rowGroup.enabled); + } + else { + if (horizontalLine) { + horizontalLine.visible = false; + } + } + } + + + ]]> + </fx:Script> + + <s:states> + <s:State name="normal"/> + <s:State name="selected"/> + <s:State name="hovered"/> + </s:states> + + <s:HGroup id="rowGroup" enabled="{!data.reversed}" width="100%" height="100%" gap="0" verticalAlign="middle"> + + <s:Group height="12" width="10" includeIn="selected,hovered"> + <s:Path data="M 0 0 L 0 16 L 16 8 z" width="100%" height="100%" top="0"> + <s:fill> + <s:SolidColor color="#000000" alpha=".5" alpha.hovered=".25"/> + </s:fill> + <s:stroke> + <s:SolidColorStroke weight="0" color="#ffffff" /> + </s:stroke> + </s:Path> + </s:Group> + + <s:Spacer width="10" includeIn="normal"/> + + + <s:BitmapImage source="{Radii8LibraryAssets.edit}" /> + + <s:Spacer width="4" /> + + <s:Label id="labelDisplay" + fontSize="11" + width="100%" + paddingTop="2" /> + </s:HGroup> + + <controls:HorizontalLine id="horizontalLine" includeIn="hovered" strokeColor="#000000" bottom="0" + alpha.hovered=".15" + visible="false"/> + +</s:ItemRenderer> \ No newline at end of file