You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2014/09/03 02:17:48 UTC
[15/30] Radii8 code base as accepted by IP Clearance
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/SyntaxHighlighter.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/SyntaxHighlighter.as b/Radii8Library/src/com/flexcapacitor/utils/SyntaxHighlighter.as
new file mode 100644
index 0000000..3f66970
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/SyntaxHighlighter.as
@@ -0,0 +1,380 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package com.flexcapacitor.utils {
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+ import flash.events.TimerEvent;
+ import flash.text.StyleSheet;
+ import flash.utils.Timer;
+
+ import mx.controls.TextArea;
+ import mx.controls.textClasses.TextRange;
+
+ import spark.components.TextArea;
+
+ import flashx.textLayout.formats.TextLayoutFormat;
+
+ import net.anirudh.as3syntaxhighlight.CodePrettyPrint;
+ import net.anirudh.as3syntaxhighlight.PseudoThread;
+
+
+ [Event(name="complete")]
+
+ /**
+ * Adds syntax highlighting to the text area.
+ *
+ * This class wraps around the AS3SyntaxHighlighter
+ * and makes it easier to setup the text area.
+ *
+ * This class is incomplete it appears.
+ * Some code may be from the example projects.
+ *
+ * http://code.google.com/p/as3syntaxhighlight/
+ * */
+ public class SyntaxHighlighter extends EventDispatcher {
+
+ /**
+ * spl = "var" or "function" token
+ * str = string - ("something")
+ * kwd = keyword
+ * com = comment
+ * typ = type
+ * lit = literal
+ * pun = punctuation - <,=
+ * pln = plain
+ * tag = tag - <(tag)
+ * atn = attribute name
+ * atv = attribute value - name="(value)"
+ * src = source
+ * dec = declaration
+ *
+ *
+ * */
+ public static var CRIMSON_EDITOR_CSS:String = "" +
+ ".spl {color: #4f94cd;} " +
+ ".str {color: #800080;} " +
+ ".kwd {color: #000088;} " +
+ ".com {color: #008800;} " +
+ ".typ {color: #0068CF;} " +
+ ".lit {color: #006666;} " +
+ ".pun {color: #1C02FF;} " +
+ ".tag {color: #1C02FF;} " +
+ ".pln {color: #222222;} " +
+ ".atn {color: #660066;} " +
+ ".atv {color: #880000;} " +
+ ".dec {color: #660066;}";
+
+ public function SyntaxHighlighter(textarea:Object = null) {
+
+ if (textarea is mx.controls.TextArea) {
+ this.mxTextArea = mx.controls.TextArea(textarea);
+ }
+ else if (textarea is spark.components.TextArea) {
+ this.sparkTextArea = spark.components.TextArea(textarea);
+ }
+ }
+
+ //public var cssString:String =".spl {font-family:sandboxcode;color: #4f94cd;} .str { font-family:sandboxcode; color: #880000; } .kwd { font-family:sandboxcode; color: #000088; } .com { font-family:sandboxcode; color: #008800; } .typ { font-family:sandboxcode; color: #0068CF; } .lit { font-family:sandboxcode; color: #006666; } .pun { font-family:sandboxcode; color: #666600; } .pln { font-family:sandboxcode; color: #222222; } .tag { font-family:sandboxcode; color: #000088; } .atn { font-family:sandboxcode; color: #660066; } .atv { font-family:sandboxcode; color: #880000; } .dec { font-family:sandboxcode; color: #660066; } ";
+ public var cssString:String = ".spl {color: #4f94cd;} .str {color: #880000; } .kwd {color: #000088;} .com {color: #008800;} .typ {color: #0068CF;} .lit {color: #006666;} .pun {color: #666600;} .pln {color: #222222;} .tag {color: #000088; } .atn {color: #660066;} .atv {color: #880000; } .dec {color: #660066; } ";
+ private var codeStyle:StyleSheet;
+ private var codePrettyPrint:CodePrettyPrint;
+ private var codeTimer:Timer;
+ private var asyncStop:Boolean;
+ private var asyncRunning:Boolean;
+ private var codeStylePF:StyleSheet;
+ private var srclenPF:int;
+ private var arrPF:Array;
+ private var lenPF:int;
+ private var firstNodePF:Boolean;
+ private var firstIndexPF:int;
+ private var pfasyncrunning:Boolean;
+ private var pfasyncstop:Boolean;
+ private var desclenPF:int;
+ private var colorThread:PseudoThread;
+
+ public var debug:Boolean;
+
+ public var dispatchEvents:Boolean = true;
+
+ /**
+ * Interval in milliseconds to wait before.
+ * Not sure this is working.
+ * */
+ public var timerInterval:int = 200;
+
+ /**
+ * MX TextArea
+ * */
+ [Bindable]
+ public var mxTextArea:mx.controls.TextArea;
+
+ /**
+ * Spark TextArea
+ * */
+ [Bindable]
+ public var sparkTextArea:spark.components.TextArea;
+
+ [Bindable]
+ private var asyncCodeState:String;
+
+ /**
+ * Highlights the code in the text area
+ * */
+ public function highlightCode():void {
+ if (!codeTimer) {
+ codeTimer = new Timer(timerInterval, 1);
+ codeTimer.addEventListener(TimerEvent.TIMER, doPrettyPrint);
+ }
+
+ if (codeTimer.running) {
+ codeTimer.stop();
+ }
+
+ codeTimer.reset();
+ // wait for some time to see if we need to highlight or not
+ codeTimer.start();
+ //trace("start highlighting gettimer=" + getTimer());
+
+ doPrettyPrint();
+ }
+
+ /**
+ *
+ * */
+ private function doPrettyPrint(event:TimerEvent=null):void {
+ //trace("start doPrettyPrint gettimer=" + getTimer());
+ if (!codeStyle) {
+ codeStyle = new StyleSheet();
+ codePrettyPrint = new CodePrettyPrint();
+ codeStyle.parseCSS(cssString);
+ }
+
+ if (codePrettyPrint.asyncRunning) {
+ codePrettyPrint.prettyPrintStopAsyc = true;
+ if (mxTextArea) {
+ mxTextArea.callLater(doPrettyPrint);
+ }
+ else if (sparkTextArea) {
+ sparkTextArea.callLater(doPrettyPrint);
+ }
+ return;
+ }
+
+ if (pfasyncrunning) {
+ pfasyncstop = true;
+ if (mxTextArea) {
+ mxTextArea.callLater(doPrettyPrint);
+ }
+ else if (sparkTextArea) {
+ sparkTextArea.callLater(doPrettyPrint);
+ }
+ return;
+ }
+
+ //trace("start code in place gettimer=" + getTimer());
+ codeHighlightInPlace();
+
+ }
+
+ private function pfinit(startIndex:int, endIndex:int):void {
+ codeStylePF = codeStyle;
+ srclenPF = endIndex - startIndex;
+ arrPF = codePrettyPrint.mainDecorations;
+ lenPF = arrPF.length;
+ desclenPF = mxTextArea ? mxTextArea.text.length : sparkTextArea.text.length;
+ firstNodePF = false;
+ firstIndexPF = 0;
+ pfasyncrunning = false;
+ pfasyncstop = false;
+ }
+
+
+ private function processFormattedCodeAsync(startIndex:int, endIndex:int, completeFunction:Function, optIdx:int=0):Boolean {
+
+ if (pfasyncstop) {
+ pfasyncrunning = false;
+ pfasyncstop = false;
+ return false;
+ }
+
+ pfasyncrunning = true;
+
+ if (arrPF==null || srclenPF<1) {
+ pfasyncrunning = false;
+ return false;
+ }
+
+ if (debug) trace("color worker " + optIdx);
+ var tr:TextRange;
+ var txtLayFmt:TextLayoutFormat;
+ var thecolor:Object;
+ var i:int = optIdx;
+
+ if ( i > 0 && i % 5 == 0 ) {
+ asyncCodeState = "Coloring (" + int((i / lenPF) * 100) + "%)...";
+ }
+
+ var textLength:int;
+
+ if (mxTextArea) {
+ textLength = mxTextArea.text.length;
+ }
+ else if (sparkTextArea) {
+ textLength = sparkTextArea.text.length;
+ }
+
+ if ( i < lenPF ) {
+
+ /* find first node */
+ if ( arrPF[i] == 0 && firstNodePF == false ) {
+ firstNodePF = true;
+ return true;
+ }
+ else if ( arrPF[i] == 0 && firstNodePF == true ) {
+ firstNodePF = false;
+ firstIndexPF = i;
+ }
+
+ if ( i - 2 > 0 ) {
+ if ( arrPF[i-2] != arrPF[i] && arrPF[i] < textLength )
+ {
+
+
+ if (mxTextArea) {
+ tr = new TextRange(mxTextArea, false, arrPF[i-2] + startIndex, arrPF[i] + startIndex);
+ thecolor = codeStylePF.getStyle("." + arrPF[i-1]).color;
+ // RangeError: Error #2006: The supplied index is out of bounds.
+ // if we are not on the stage
+ tr.color = thecolor;
+ }
+ else if (sparkTextArea) {
+ //var txtLayFmt:TextLayoutFormat = sparkTextArea.getFormatOfRange(null, start, end);
+ txtLayFmt = sparkTextArea.getFormatOfRange(null, arrPF[i-2] + startIndex, arrPF[i] + startIndex);
+ txtLayFmt.color = codeStylePF.getStyle("." + arrPF[i-1]).color;
+ sparkTextArea.setFormatOfRange(txtLayFmt, arrPF[i-2] + startIndex, arrPF[i] + startIndex);
+ }
+ }
+
+ }
+ return true;
+
+
+ }
+
+ if ( i > 0 ) {
+ i -= 2;
+
+ if ( arrPF[i] + startIndex < endIndex ) {
+
+ if (mxTextArea) {
+ tr = new TextRange(mxTextArea, false, arrPF[i] + startIndex, endIndex);
+ thecolor = codeStylePF.getStyle("." + arrPF[i+1]).color;
+ }
+ else if (sparkTextArea) {
+ txtLayFmt = sparkTextArea.getFormatOfRange(null, arrPF[i] + startIndex, endIndex);
+ txtLayFmt.color = codeStylePF.getStyle("." + arrPF[i-1]).color;
+ }
+
+ var totalLength:int = mxTextArea ? mxTextArea.text.length : sparkTextArea.text.length;
+
+ if ( totalLength >= endIndex ) {
+ if (mxTextArea) {
+ tr.color = thecolor;
+ }
+ else if (sparkTextArea) {
+ sparkTextArea.setFormatOfRange(txtLayFmt, arrPF[i] + startIndex, endIndex);
+ }
+ }
+
+ }
+ }
+
+ if ( completeFunction != null ) {
+ completeFunction();
+ }
+
+ if (debug) trace("color worker done");
+ pfasyncrunning = false;
+ return false;
+
+ }
+
+ private function codePFComplete():void {
+ asyncCodeState = "";
+
+ if (dispatchEvents) {
+ dispatchEvent(new Event(Event.COMPLETE));
+ }
+ }
+
+ private function codeInPlaceComplete():void {
+ asyncCodeState = "Coloring...";
+
+ if (dispatchEvents && hasEventListener(Event.OPEN)) {
+ dispatchEvent(new Event(Event.OPEN));
+ }
+
+ if (pfasyncrunning) {
+ pfasyncstop = true;
+
+ if (mxTextArea) {
+ mxTextArea.callLater(codeInPlaceComplete);
+ }
+ else if (sparkTextArea) {
+ sparkTextArea.callLater(codeInPlaceComplete);
+ }
+ return;
+ }
+
+ asyncRunning = false;
+
+ if (mxTextArea) {
+ pfinit(0, mxTextArea.text.length);
+ colorThread = new PseudoThread(mxTextArea.systemManager, processFormattedCodeAsync, this, [0, mxTextArea.text.length, codePFComplete, 0], 3, 2);
+ }
+ else if (sparkTextArea) {
+ pfinit(0, sparkTextArea.text.length);
+ colorThread = new PseudoThread(sparkTextArea.systemManager, processFormattedCodeAsync, this, [0, sparkTextArea.text.length, codePFComplete, 0], 3, 2);
+ }
+ }
+
+ private function lexInt(index:int, total:int):void {
+ if ( index > 0 && index % 5 == 0 ) {
+ asyncCodeState = "Lexing (" + int((index / total) * 100) + "%)...";
+ }
+ }
+
+ private function codeHighlightInPlace():void {
+ asyncRunning = true;
+ asyncCodeState = "Lexing...";
+
+ if (mxTextArea) {
+ codePrettyPrint.prettyPrintAsync(mxTextArea.text, null, codeInPlaceComplete, lexInt, mxTextArea.systemManager);
+ }
+ else if (sparkTextArea) {
+ codePrettyPrint.prettyPrintAsync(sparkTextArea.text, null, codeInPlaceComplete, lexInt, sparkTextArea.systemManager);
+ }
+
+ if (dispatchEvents) {
+ dispatchEvent(new Event(Event.INIT));
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/supportClasses/DragData.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/supportClasses/DragData.as b/Radii8Library/src/com/flexcapacitor/utils/supportClasses/DragData.as
new file mode 100644
index 0000000..388195a
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/supportClasses/DragData.as
@@ -0,0 +1,58 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package com.flexcapacitor.utils.supportClasses {
+ import flash.geom.Point;
+
+ import spark.components.supportClasses.GroupBase;
+ import spark.layouts.supportClasses.DropLocation;
+ import spark.layouts.supportClasses.LayoutBase;
+
+ /**
+ *
+ * */
+ public class DragData {
+
+
+ public function DragData()
+ {
+
+ }
+
+ public var offscreen:Boolean;
+ public var isApplication:Boolean;
+ public var isGroup:Boolean;
+ public var isSkinnableContainer:Boolean;
+ public var isVisualElementContainer:Boolean;
+ public var isBasicLayout:Boolean;
+ public var isTile:Boolean;
+ public var isVertical:Boolean;
+ public var isHorizontal:Boolean;
+ public var targetGroupLayout:LayoutBase;
+ public var targetGroup:GroupBase;
+ public var target:Object;
+ public var targetsUnderPoint:Array;
+ public var topLeftEdgePoint:Point;
+ public var description:ComponentDescription;
+ public var dropLocation:DropLocation;
+ public var dropIndex:int;
+ public var dropPoint:Point;
+ public var layout:LayoutBase;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/supportClasses/ISelectionGroup.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/supportClasses/ISelectionGroup.as b/Radii8Library/src/com/flexcapacitor/utils/supportClasses/ISelectionGroup.as
new file mode 100644
index 0000000..9c4cd11
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/supportClasses/ISelectionGroup.as
@@ -0,0 +1,41 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package com.flexcapacitor.utils.supportClasses {
+
+ public interface ISelectionGroup {
+
+
+ function get showSelectionFill():Boolean;
+ function set showSelectionFill(value:Boolean):void;
+
+ function get showSelectionFillOnDocument():Boolean;
+ function set showSelectionFillOnDocument(value:Boolean):void;
+
+ function get showSelectionLabel():Boolean;
+ function set showSelectionLabel(value:Boolean):void;
+
+ function get showSelectionLabelOnDocument():Boolean;
+ function set showSelectionLabelOnDocument(value:Boolean):void;
+
+ function get selectionBorderColor():uint;
+ function set selectionBorderColor(value:uint):void;
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/supportClasses/TargetSelectionGroup.mxml
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/supportClasses/TargetSelectionGroup.mxml b/Radii8Library/src/com/flexcapacitor/utils/supportClasses/TargetSelectionGroup.mxml
new file mode 100644
index 0000000..2bbfbe3
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/supportClasses/TargetSelectionGroup.mxml
@@ -0,0 +1,216 @@
+<?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"
+
+ autoDrawBackground="false"
+ mouseChildren="false"
+ mouseEnabled="false"
+ buttonMode="false"
+ mouseEnabledWhereTransparent="false"
+ width="20" height="20"
+ implements="com.flexcapacitor.utils.supportClasses.ISelectionGroup"
+ >
+
+
+ <fx:Script>
+ <![CDATA[
+ import com.flexcapacitor.controller.Radiate;
+ import com.flexcapacitor.model.IDocument;
+
+ import mx.core.mx_internal;
+ import mx.events.DragEvent;
+ import mx.utils.NameUtil;
+
+ use namespace mx_internal;
+
+
+
+ override public function set data(value:Object):void {
+ super.data = value;
+
+
+ // check if target is component and is not skin
+ // should not be a skin
+ labelDisplay.text = NameUtil.getUnqualifiedClassName(data);
+
+ }
+
+ protected function itemrenderer1_mouseMoveHandler(event:MouseEvent):void
+ {
+ trace("selection group is getting mouse events");
+ dispatchEvent(event.clone());
+ }
+
+ protected function itemrenderer1_dragOverHandler(event:DragEvent):void
+ {
+ trace("selection group is getting drag events");
+ dispatchEvent(event.clone());
+ }
+
+ private var _showSelectionFill:Boolean = true;
+
+ public function get showSelectionFill():Boolean {
+ return _showSelectionFill;
+ }
+
+ public function set showSelectionFill(value:Boolean):void {
+ _showSelectionFill = value;
+ invalidateDisplayList();
+ }
+
+
+ private var _showSelectionFillOnDocument:Boolean = true;
+
+ public function get showSelectionFillOnDocument():Boolean {
+ return _showSelectionFillOnDocument;
+ }
+
+ public function set showSelectionFillOnDocument(value:Boolean):void {
+ _showSelectionFillOnDocument = value;
+ invalidateDisplayList();
+ }
+
+
+ private var _showSelectionLabel:Boolean = true;
+
+ public function get showSelectionLabel():Boolean {
+ return _showSelectionLabel;
+ }
+
+ public function set showSelectionLabel(value:Boolean):void {
+ _showSelectionLabel = value;
+ invalidateDisplayList();
+ }
+
+
+ private var _showSelectionLabelOnDocument:Boolean = true;
+
+ public function get showSelectionLabelOnDocument():Boolean {
+ return _showSelectionLabelOnDocument;
+ }
+
+ public function set showSelectionLabelOnDocument(value:Boolean):void {
+ _showSelectionLabelOnDocument = value;
+ invalidateDisplayList();
+ }
+
+
+ private var _selectionBorderColor:uint = 0x2da6e9;
+
+ public function get selectionBorderColor():uint {
+ return _selectionBorderColor;
+ }
+
+ public function set selectionBorderColor(value:uint):void {
+ if (_selectionBorderColor==value) return;
+
+ _selectionBorderColor = value;
+
+ invalidateDisplayList();
+ }
+
+
+
+ override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+ super.updateDisplayList(unscaledWidth, unscaledHeight);
+ var radiate:Radiate = Radiate.getInstance();
+ var documentDescription:IDocument = radiate.selectedDocument;
+ //graphics.clear();
+ /*
+ was showing previous selection like the graphics weren't cleared
+ selectionFill.width = unscaledWidth;
+ selectionFill.height = unscaledHeight;
+ selectionStroke.width = unscaledWidth;
+ selectionStroke.height = unscaledHeight;*/
+ var solidColorStroke:SolidColorStroke = SolidColorStroke(selectionStroke.stroke);
+ if (selectionStroke &&
+ solidColorStroke.color != selectionBorderColor) {
+ solidColorStroke.color = selectionBorderColor;
+ labelDisplay.setStyle("backgroundColor", selectionBorderColor);
+ }
+
+ // hide or show background fill
+ if (showSelectionFill) {
+
+ if (documentDescription && documentDescription.instance == data && !showSelectionFillOnDocument) {
+ selectionFill.visible = false;
+ }
+ else {
+ selectionFill.visible = true;
+ }
+ }
+ else {
+ selectionFill.visible = false;
+ }
+
+ // hide or show label
+ if (showSelectionLabel) {
+
+ if (documentDescription && documentDescription.instance == data && !showSelectionLabelOnDocument) {
+ labelDisplay.visible = false;
+ }
+ else {
+ labelDisplay.visible = true;
+ }
+ }
+ else {
+ labelDisplay.visible = false;
+ }
+
+ }
+
+
+ ]]>
+ </fx:Script>
+
+
+ <s:Rect id="selectionFill" width="{width}" height="{height}">
+ <s:fill>
+ <s:SolidColor color="0x2da6e9" alpha=".08" />
+ </s:fill>
+ </s:Rect>
+
+ <s:Rect id="selectionStroke" width="{width}" height="{height}">
+ <s:stroke>
+ <s:SolidColorStroke color="0x2da6e9" weight="0" alpha="1"/>
+ </s:stroke>
+ </s:Rect>
+
+ <s:Label id="labelDisplay"
+ top="-14"
+ fontSize="9"
+ typographicCase="uppercase"
+ text="Group"
+ textAlign="center"
+ verticalAlign="middle"
+ height="14"
+ paddingLeft="5"
+ paddingRight="5"
+ fontWeight="bold"
+ color="0xffffff"
+ backgroundColor="0x2da6e9"
+ backgroundAlpha=".9"
+ mouseChildren="false"
+ mouseEnabled="false"
+ />
+ <!--<s:Button bottom="-5" label="clicable?" click="trace('clicked')"/>-->
+</s:ItemRenderer>
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/BlendMode.mxml
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/views/BlendMode.mxml b/Radii8Library/src/com/flexcapacitor/views/BlendMode.mxml
new file mode 100644
index 0000000..8d53a5d
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/views/BlendMode.mxml
@@ -0,0 +1,217 @@
+<?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:fc="com.flexcapacitor.controls.*"
+ xmlns:fx="http://ns.adobe.com/mxml/2009"
+ xmlns:mx="library://ns.adobe.com/flex/mx"
+ xmlns:s="library://ns.adobe.com/flex/spark"
+ xmlns:utils="com.flexcapacitor.utils.*"
+ xmlns:handlers="com.flexcapacitor.handlers.*"
+ xmlns:supportClasses="com.flexcapacitor.effects.supportClasses.*"
+ xmlns:local="*"
+
+ width="100%"
+ creationComplete="group1_creationCompleteHandler(event)"
+ >
+
+ <fx:Script>
+ <![CDATA[
+ import com.flexcapacitor.controller.Radiate;
+ import com.flexcapacitor.events.RadiateEvent;
+
+ import mx.events.FlexEvent;
+
+ import spark.events.IndexChangeEvent;
+
+ private var radiate:Radiate = Radiate.getInstance();
+ private var _target:Object;
+ private static const BLEND_MODE:String = "blendMode";
+
+ public function get target():Object {
+ return _target;
+ }
+
+ public function set target(value:Object):void {
+ if (_target == value) return;
+
+ if (!(value is DisplayObject)) {
+ _target = null;
+ blendModeCombo.selectedIndex = -1;
+ }
+ else {
+ _target = value;
+ updateSelectedBlendMode();
+ }
+ }
+
+ protected function applyPropertiesToTargetHandler(event:IndexChangeEvent = null):void {
+
+ if (target) {
+ Radiate.setProperty(target, BLEND_MODE, blendModeCombo.selectedItem.value);
+ }
+ }
+
+ protected function group1_creationCompleteHandler(event:FlexEvent):void {
+ radiate.addEventListener(RadiateEvent.TARGET_CHANGE, targetChangeHandler);
+ radiate.addEventListener(RadiateEvent.PROPERTY_CHANGED, propertyChangeHandler);
+
+ if (radiate.target) {
+ target = radiate.target;
+ }
+ }
+
+ protected function targetChangeHandler(event:RadiateEvent):void {
+ target = event.selectedItem;
+ }
+
+ protected function propertyChangeHandler(event:RadiateEvent):void {
+ var displayObject:DisplayObject = event.selectedItem as DisplayObject;
+ var currentBlendMode:String;
+ var currentIndex:int;
+
+ var properties:Array = event.properties;
+
+ for (var i:int;i<length;i++) {
+ if (properties[i]==BLEND_MODE) {
+ updateSelectedBlendMode();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Updates the list to reflect the current blend mode of the target
+ * */
+ private function updateSelectedBlendMode():void {
+ var displayObject:DisplayObject = target as DisplayObject;
+ var currentBlendMode:String;
+ var currentIndex:int;
+
+ if (displayObject) {
+ currentBlendMode = displayObject.blendMode;
+ currentIndex = getItemIndexByKeys(blendModes, {value:currentBlendMode});
+ blendModeCombo.selectedIndex = currentIndex;
+ }
+ }
+
+ /**
+ * Modified code from CASALIBRARY
+ * @modified true 9/10/2011
+ * */
+
+ /**
+ * Returns the index of the first item that match the key values of all
+ * properties of the object <code>keyValues</code>.
+
+ @param inArray: Array to search for an element with every key value in the object <code>keyValues</code>.
+ @param keyValues: An object with key value pairs.
+ @return Returns the first matched item; otherwise <code>null</code>.
+ @example
+ <code>
+ var people:Array = new Array({name: "Aaron", sex: "Male", hair: "Brown"}, {name: "Linda", sex: "Female", hair: "Blonde"}, {name: "Katie", sex: "Female", hair: "Brown"}, {name: "Nikki", sex: "Female", hair: "Blonde"});
+ var person:Object = ArrayUtil.getItemByKeys(people, {sex: "Female", hair: "Brown"});
+
+ trace(person.name); // Traces "Katie"
+ </code>
+ */
+ public static function getItemIndexByKeys(array:Array, keyValues:Object):int {
+ var i:int = -1;
+ var item:*;
+ var hasKeys:Boolean;
+
+ while (++i < array.length) {
+ item = array[i];
+ hasKeys = true;
+
+ for (var j:String in keyValues) {
+ if (!(j in item) || item[j] != keyValues[j]) {
+ hasKeys = false;
+ }
+ }
+
+ if (hasKeys) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+
+ ]]>
+ </fx:Script>
+
+ <fx:Declarations>
+
+ <!--
+
+ // If one of the non-native Flash blendModes is set,
+ // record the new value and set the appropriate
+ // blendShader on the display object.
+
+ value =="colordodge"
+ value =="colorburn"
+ value =="exclusion"
+ value =="softlight"
+ value =="hue"
+ value =="saturation"
+ value =="color"
+ value =="luminosity"
+ -->
+
+ <fx:Array id="blendModes">
+ <fx:Object label="Auto" value="auto"/>
+ <fx:Object label="Add" value="add"/>
+ <fx:Object label="Alpha" value="alpha"/>
+ <fx:Object label="Color" value="color"/>
+ <fx:Object label="Color Burn" value="colorburn"/>
+ <fx:Object label="Color Dodge" value="colordodge"/>
+ <fx:Object label="Darken" value="darken"/>
+ <fx:Object label="Difference" value="difference"/>
+ <fx:Object label="Erase" value="erase"/>
+ <fx:Object label="Exclusion" value="exclusion"/>
+ <fx:Object label="Hardlight" value="hardlight"/>
+ <fx:Object label="Hue" value="hue"/>
+ <fx:Object label="Invert" value="invert"/>
+ <fx:Object label="Layer" value="layer"/>
+ <fx:Object label="Lighten" value="lighten"/>
+ <fx:Object label="Luminosity" value="luminosity"/>
+ <fx:Object label="Multiply" value="multiply"/>
+ <fx:Object label="Normal" value="normal"/>
+ <fx:Object label="Overlay" value="overlay"/>
+ <fx:Object label="Saturation" value="saturation"/>
+ <fx:Object label="Screen" value="screen"/>
+ <fx:Object label="Softlight" value="softlight"/>
+ <fx:Object label="Subtract" value="subtract"/>
+ <fx:Object label="Normal" value="normal"/>
+ </fx:Array>
+
+ <s:ArrayCollection id="blendModesCollection" source="{blendModes}"/>
+ </fx:Declarations>
+
+ <s:DropDownList id="blendModeCombo"
+ interactionMode="mouse"
+ width="100%"
+ left="4"
+ change="applyPropertiesToTargetHandler(event)"
+ focusOut="applyPropertiesToTargetHandler()"
+ dataProvider="{blendModesCollection}">
+ </s:DropDownList>
+
+</s:Group>
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/Breadcrumbs.mxml
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/views/Breadcrumbs.mxml b/Radii8Library/src/com/flexcapacitor/views/Breadcrumbs.mxml
new file mode 100644
index 0000000..3e2c64b
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/views/Breadcrumbs.mxml
@@ -0,0 +1,309 @@
+<?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:controls="com.flexcapacitor.graphics.*"
+ xmlns:fx="http://ns.adobe.com/mxml/2009"
+ xmlns:mx="library://ns.adobe.com/flex/mx"
+ xmlns:s="library://ns.adobe.com/flex/spark"
+ width="100%"
+ minWidth="80"
+ creationComplete="creationCompleteHandler(event)">
+
+ <!-- Consider width and height to be 100% -->
+
+ <fx:Script>
+ <![CDATA[
+ import com.flexcapacitor.controller.Radiate;
+ import com.flexcapacitor.events.RadiateEvent;
+ import com.flexcapacitor.model.IDocument;
+ import com.flexcapacitor.model.VisualElementVO;
+ import com.flexcapacitor.utils.InspectorUtils;
+
+ import mx.collections.ArrayCollection;
+ import mx.core.IVisualElement;
+ import mx.events.FlexEvent;
+
+ import spark.components.Application;
+
+ [Bindable]
+ public var dataProviderList:ArrayCollection = new ArrayCollection();
+
+ [Bindable]
+ public var itemDescription:String;
+
+ [Bindable]
+ public var parentDocumentName:String;
+
+ public var maxDepth:int = 50;
+
+
+ public var radiate:Radiate = Radiate.instance;
+
+ /**
+ * Flag for commit properties
+ * */
+ private var targetChanged:Boolean;
+
+ /**
+ * Displays the ID of the component if available
+ * */
+ private var showID:String;
+
+ /**
+ * When true sets the bread crumbs with the
+ * target on the right and ancestors on the left
+ * */
+ public var showRightToLeft:Boolean = true;
+
+ /**
+ * Components tree
+ * */
+ private var componentsTree:Array = [];
+
+ private var _target:Object;
+ public function get target():* {
+ return _target;
+ }
+
+ /**
+ * This is set automatically when a new target is selected
+ * This can be any type. You must disable this component if the
+ * type is not what you can process.
+ * */
+ [Bindable]
+ public function set target(value:*):void {
+ _target = value;
+ targetChanged = true;
+ invalidateProperties();
+ }
+
+
+ private function mouseUpHandler(event:MouseEvent):void {
+ var isDraggable:Boolean = event.target as Sprite;
+ var isParentDraggable:Boolean = (event.target.parent != null && event.target.parent is Sprite);
+
+ radiate.dispatchTargetChangeEvent(event.target);
+ }
+
+
+ protected function list1_clickHandler(event:MouseEvent):void {
+ if (list.selectedItem) {
+ var element:DisplayObject = VisualElementVO(list.selectedItem).element as DisplayObject;
+
+ if (element!=target) {
+ radiate.dispatchTargetChangeEvent(element);
+ }
+ }
+ }
+
+ protected function creationCompleteHandler(event:FlexEvent):void {
+ radiate.addEventListener(RadiateEvent.TARGET_CHANGE, targetChangeHandler, false, 0, true);
+ radiate.addEventListener(RadiateEvent.ADD_ITEM, addChangeHandler, false, 0, true);
+ radiate.addEventListener(RadiateEvent.MOVE_ITEM, moveChangeHandler, false, 0, true);
+
+ if (radiate.targets) {
+ target = radiate.target;
+ }
+ }
+
+ protected function addChangeHandler(event:Event):void {
+
+ }
+
+ protected function moveChangeHandler(event:Event):void {
+
+ }
+
+ protected function targetChangeHandler(event:RadiateEvent):void {
+ target = event.selectedItem;
+
+ // if target is null clear bookmarks
+ if (!target) {
+
+ }
+
+
+ }
+
+ override protected function commitProperties():void {
+ super.commitProperties();
+
+ if (targetChanged) {
+ createBreadCrumbTrail();
+ targetChanged = false;
+ invalidateDisplayList();
+ }
+
+ }
+
+ private function createBreadCrumbTrail():void {
+ var parentDocument:IDocument = radiate.selectedDocument;
+ var lastElement:IVisualElement;
+ var newScrollPosition:int;
+ var displayItems:Array;
+
+ if (!target) {
+ dataProviderList.source = [];
+ return;
+ }
+
+ componentsTree.length = 0;
+ if (target is IDocument) target = parentDocument.instance;
+ componentsTree = InspectorUtils.getVisualElementsArray(target, componentsTree, maxDepth, parentDocument.instance);
+ //DisplayObjectUtils.walkUpTree(target, processTree);
+
+ if (!componentsTree) {
+ dataProviderList.source = [];
+ return;
+ }
+
+ componentsTree.forEach(labelFunction);
+
+ if (showRightToLeft) {
+ componentsTree.reverse();
+ dataProviderList.source = componentsTree;
+
+ // NOTE: this is the only way i've been able to get it to work
+ // and a developer in the flex sdk recommends a similar solution
+ list.validateNow();
+
+ if (list.scroller.viewport.contentWidth>list.width) {
+ newScrollPosition = list.scroller.viewport.contentWidth - list.width;
+ }
+
+ list.scroller.viewport.horizontalScrollPosition = newScrollPosition;
+ list.validateNow();
+
+ // check again
+ if (list.scroller.viewport.contentWidth>list.width) {
+ newScrollPosition = list.scroller.viewport.contentWidth - list.width;
+ }
+
+ list.scroller.viewport.horizontalScrollPosition = newScrollPosition;
+ list.validateNow();
+
+ if (componentsTree.length) {
+ list.selectedIndex = componentsTree.length-1;
+ }
+ }
+ else {
+ dataProviderList.source = componentsTree;
+ if (componentsTree.length) {
+ list.selectedIndex = 0;
+ }
+ }
+ }
+
+ public function labelFunction(item:VisualElementVO, itemIndex:int, array:Array):void {
+ var label:String = item.id && showID ? item.type + "." + item.id : item.type;
+
+
+ if (item.element is Application) {
+ label = "Document";
+ }
+
+ if (showRightToLeft) {
+ if (itemIndex!=0) {
+ label = label + " > ";
+ }
+ }
+ else {
+ if (itemIndex!=array.length-1) {
+ label = label + " > ";
+ }
+
+ }
+
+ item.label = label;
+ }
+
+
+
+ ]]>
+ </fx:Script>
+
+ <!-- IF THIS IS TOO BIG SET THE HEIGHT IN THE INSTANCE -->
+ <s:Group width="100%">
+
+ <s:List id="list"
+ contentBackgroundColor="#ffffff"
+ contentBackgroundAlpha="0"
+ width="100%"
+ minHeight="16"
+ dataProvider="{dataProviderList}"
+ borderVisible="false"
+ labelField="label"
+ click="list1_clickHandler(event)"
+ horizontalScrollPolicy="auto"
+ verticalScrollPolicy="off">
+
+ <s:layout>
+ <s:HorizontalLayout gap="4" useVirtualLayout="false" />
+ </s:layout>
+
+ <s:itemRenderer>
+ <fx:Component>
+ <s:ItemRenderer width="100%" autoDrawBackground="false" minHeight="14"
+ useHandCursor="true" buttonMode="true">
+
+ <s:states>
+ <s:State name="normal"/>
+ <s:State name="hovered"/>
+ <s:State name="selected"/>
+ </s:states>
+ <s:Label id="labelDisplay"
+ fontSize="11"
+ typographicCase="lowercaseToSmallCaps"
+ fontWeight="normal"
+ verticalCenter="0"
+ color="#585858"
+ color.hovered="#787878"
+ color.selected="#383838"
+ />
+
+ <!-- dark background colors -->
+ <!--
+ color="#BBBBBB"
+ color.hovered="#DDDDDD"
+ color.selected="#FFFFFF"
+ -->
+
+ <!-- light background colors -->
+ <!--
+ color="#585858"
+ color.hovered="#787878"
+ color.selected="#383838"
+ -->
+ </s:ItemRenderer>
+ </fx:Component>
+ </s:itemRenderer>
+
+ </s:List>
+
+ <s:Label text="No selection"
+ fontSize="11"
+ verticalAlign="middle"
+ height="{list.height}"
+ visible="{dataProviderList.length==0}"
+ includeInLayout="{dataProviderList.length==0}"
+ typographicCase="lowercaseToSmallCaps"/>
+ </s:Group>
+
+
+</s:Group>
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/ChangeHistory.mxml
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/views/ChangeHistory.mxml b/Radii8Library/src/com/flexcapacitor/views/ChangeHistory.mxml
new file mode 100644
index 0000000..eff3965
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/views/ChangeHistory.mxml
@@ -0,0 +1,408 @@
+<?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:handlers="com.flexcapacitor.handlers.*"
+ xmlns:status="com.flexcapacitor.effects.status.*"
+ xmlns:core="com.flexcapacitor.effects.core.*"
+ xmlns:clipboard="com.flexcapacitor.effects.clipboard.*"
+ xmlns:file="com.flexcapacitor.effects.file.*"
+ xmlns:popup="com.flexcapacitor.effects.popup.*"
+ xmlns:controls="com.flexcapacitor.controls.*"
+
+ width="400" height="24"
+ >
+
+ <fx:Script>
+ <![CDATA[
+ import com.flexcapacitor.controller.Radiate;
+ import com.flexcapacitor.events.HistoryEvent;
+ import com.flexcapacitor.events.HistoryEventItem;
+ import com.flexcapacitor.utils.ClassUtils;
+ import com.flexcapacitor.utils.DisplayObjectUtils;
+ import com.flexcapacitor.utils.XMLUtils;
+ import com.flexcapacitor.utils.supportClasses.ComponentDescription;
+
+ import mx.collections.ArrayCollection;
+ import mx.collections.XMLListCollection;
+ import mx.core.IVisualElement;
+ import mx.effects.effectClasses.PropertyChanges;
+ import mx.states.AddItems;
+
+ public var radiate:Radiate = Radiate.instance;
+
+ /**
+ * List of changes
+ * */
+ [Bindable]
+ public var xml:XML;
+
+ /**
+ * List of changes in XML as a string
+ * Contains the same value as if calling xml.toXMLString();
+ * */
+ [Bindable]
+ public var changesText:String;
+
+ /**
+ * Removes duplicate changes.
+ * If checkbox1 height is set to 20 and then later set to 30
+ * then the first entry is removed.
+ * */
+ public var removeDuplicates:Boolean = true;
+
+ /**
+ * Removes the search pattern for finding in eclipse
+ * */
+ private var includeExpression:Boolean;
+ private var reversePathOrder:Object;
+
+ public function getHistory():String {
+ var history:ArrayCollection = Radiate.history;
+ var totalHistoryLength:int = history.length;
+ var currentHistoryIndex:int = Radiate.historyIndex;
+ var changesDictionary:Dictionary = Radiate.historyEventsDictionary;
+ var items:XMLListCollection = new XMLListCollection();
+ var propertyChange:PropertyChanges;
+ var setStartValues:Boolean = true;
+ var changesCollection:XMLListCollection;
+ var genericCollection:XMLListCollection;
+ var documentTree:ComponentDescription;
+ var historyEvent:HistoryEventItem;
+ var propertiesList:XMLList;
+ var targetsList:XMLList;
+ var historyArray:Array;
+ var changesLength:int;
+ var properties:Array;
+ var targetCount:uint;
+ var propertyItem:XML;
+ var addItem:AddItems;
+ var property:String;
+ var changeItem:XML;
+ var targetItem:XML;
+ var changes:Array;
+ var change:Object;
+ var targets:Array;
+ var target:Object;
+ var item:XML;
+
+
+ if (currentHistoryIndex==-1) {
+ return "No changes";
+ }
+
+ // get current changes
+ historyArray = history.length ? history.getItemAt(currentHistoryIndex) as Array : null;
+ change = historyArray && historyArray.length ? historyArray[0] as PropertyChanges: null;
+
+ // get property change description object
+ historyEvent = Radiate.historyEventsDictionary[change];
+
+ // create default xml
+ xml = <root><items/></root>;
+
+ // get document tree for getting path names later
+ documentTree = radiate.selectedDocument.componentDescription;
+
+ return "Not supported at this time";
+ // THIS IS OLDER CODE IT NEEDS TO BE REFACTORED
+
+ // loop through changes and create change items
+ for (var i:int;i<totalHistoryLength;i++) {
+ item = <item/>;
+
+ // get changes
+ historyEvent = HistoryEvent(history.getItemAt(i));
+
+ //changes = HistoryEvent(history.getItemAt(i));
+ changesLength = changes.length;
+
+ // reset changes
+ changesCollection = new XMLListCollection();
+
+ // reset properties and targets
+ genericCollection = new XMLListCollection();
+
+ for (var j:int=0;j<changesLength;j++) {
+ changeItem = <change/>;
+ change = changes[j];
+ historyEvent = changesDictionary[change];
+
+ // create item
+ changeItem.@target = ""; // set it later but define it so it is listed first
+ changeItem.@description = historyEvent.description;
+ changeItem.@type = ClassUtils.getClassName(change);
+
+ ///////////////////////////////////////
+ // PROPERTY CHANGES
+ ///////////////////////////////////////
+ if (change is PropertyChanges) {
+ propertyChange = change as PropertyChanges;
+
+ // add properties
+ properties = historyEvent.properties;
+
+ genericCollection = new XMLListCollection();
+
+ changeItem.properties = <properties/>;
+
+ for each (property in properties) {
+ propertyItem = <property/>;
+ propertyItem.@name = property;
+
+ propertyItem.startValue = String(change.start[property]);
+ propertyItem.endValue = String(change.end[property]);
+
+ genericCollection.addItem(propertyItem);
+ }
+
+ propertiesList = genericCollection.source;
+
+ changeItem.properties.appendChild(propertiesList);
+
+ }
+ else if (change is AddItems) {
+ addItem = change as AddItems;
+ changeItem.destinationClass = ClassUtils.getClassName(addItem.destination);
+ changeItem.destination = DisplayObjectUtils.getVisualElementPath(addItem.destination as IVisualElement, documentTree, reversePathOrder);
+ changeItem.position = addItem.position;
+ changeItem.propertyName = addItem.propertyName;
+ changeItem.relativeTo = DisplayObjectUtils.getVisualElementPath(addItem.relativeTo as IVisualElement, documentTree, reversePathOrder);
+ changeItem.isArray = addItem.isArray;
+ }
+
+
+ ///////////////////////////////////////
+ // ADD TARGETS
+ ///////////////////////////////////////
+ changeItem.targets = <targets/>;
+
+ targetsList = changeItem.child("targets");
+ targets = historyEvent.targets;
+ targetCount = targets.length;
+
+ // store targets
+ genericCollection = new XMLListCollection();
+
+ for each (target in targets) {
+ targetItem = <target/>;
+ changeItem.@target = changeItem.@target!="" ? ", " + ClassUtils.getClassName(target) : ClassUtils.getClassName(target);
+ targetItem.className = ClassUtils.getClassName(target);
+ targetItem.id = ClassUtils.getIdentifierOrName(target) || "";
+
+
+ if (target is DisplayObject && includeExpression && targetItem.id) {
+ targetItem.expression = <expression/>;
+ targetItem.expression.content = XMLUtils.encloseInCDATA(ClassUtils.getRegExpSearchPattern(DisplayObject(target)));
+ }
+
+ // if getting unique location find in and describe from within component tree
+ //targetItem.uniqueIdentity = Object(target).toString();
+ targetItem.path = DisplayObjectUtils.getVisualElementPath(target as IVisualElement, documentTree, reversePathOrder);
+
+ genericCollection.addItem(targetItem);
+ }
+
+ targetsList = genericCollection.source;
+
+ // add targets property change
+ changeItem.targets.appendChild(targetsList);
+
+ // add changes to change collection
+ changesCollection.addItem(changeItem);
+ }
+
+ // add changes to item
+ item.appendChild(changesCollection.source);
+
+ // add item to items collection
+ items.addItem(item);
+ }
+
+
+ if (removeDuplicates) {
+ items.source = removeDuplicateItems(items.source);
+ }
+
+ // add all item nodes to items node
+ xml.items.appendChild(items.source);
+
+ // add xml header
+ changesText = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "\n" + xml.toXMLString();
+
+
+ return changesText;
+ }
+
+ /**
+ * Removes duplicate items from the change history
+ * */
+ public function removeDuplicateItems(changes:XMLList):XMLList {
+ var changesCollection:XMLListCollection = new XMLListCollection(changes);
+ var length:uint = changesCollection.length;
+ var targetsCollection:XMLListCollection;
+ var duplicateChanges:XMLList;
+ var removeArray:Array = [];
+ var uniqueIdentity:String;
+ var propertyName:String;
+ var targetsList:XMLList;
+ var removeLength:uint;
+ var targetLength:uint;
+ var changeCount:uint;
+ var changeItem:XML;
+ var targets:Object;
+ var change:XML;
+
+ // loop through changes
+ for (var i:uint;i<length;i++) {
+ change = changesCollection.getItemAt(i) as XML;
+ propertyName = change.@property;
+ targetsList = change.child("targets");
+ targetsCollection = new XMLListCollection(targetsList);
+ targetLength = targetsList.length();
+
+ // loop through targets
+ for (var j:uint=0;j<targetLength;j++) {
+ targets = targetsCollection.getItemAt(j);
+ uniqueIdentity = targets.target.uniqueIdentity;
+
+ // check if same property is set again
+ // get all items that contain current target and property
+ duplicateChanges = changes.(targets.target.uniqueIdentity==uniqueIdentity && @property==propertyName);
+
+ changeCount = duplicateChanges.length();
+
+ if (changeCount>1) {
+ for (var k:uint=0;k<changeCount-1;k++) {
+ removeArray.push(duplicateChanges[k]);
+ }
+ }
+ }
+ }
+
+ removeLength = removeArray.length;
+
+ while (removeLength--) {
+ if (removeArray.indexOf(changesCollection.getItemAt(removeLength)) > -1) {
+ changesCollection.removeItemAt(removeLength);
+ }
+ }
+
+ return changesCollection.source;
+ }
+ ]]>
+ </fx:Script>
+
+ <fx:Declarations>
+ <!-- GET HISTORY -->
+ <handlers:EventHandler eventName="click" target="{generateLabel}">
+
+ <core:CallMethod methodName="getHistory" target="{this}"/>
+
+ <core:CopyPreviousToNext />
+
+ <popup:OpenPopUp popUpType="{popUp}"
+ duration="150"
+ width="{parentApplication.width*.8}"
+ height="{parentApplication.height*.8}"/>
+ </handlers:EventHandler>
+
+ <!-- COPY TO THE CLIPBOARD -->
+ <handlers:EventHandler eventName="click" target="{copyIcon}" setTriggerEvent="true">
+
+ <clipboard:CopyToClipboard data="{changesText}" targetAncestor="{this}" allowNullData="true">
+ <clipboard:successEffect>
+ <status:ShowStatusMessage message="Changes 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>
+
+
+ <!-- EXPORT SNAPSHOT -->
+ <handlers:EventHandler eventName="click" target="{exportLabel}">
+
+
+ <file:PromptSaveAs data="{changesText}" fileExtension="xml" fileName="changes"
+ targetAncestor="{this}"/>
+
+ </handlers:EventHandler>
+
+ <fx:Component className="popUp">
+ <s:Panel >
+ <fx:Declarations>
+ <fx:Object id="data"/>
+ </fx:Declarations>
+ <s:TextArea id="popUpTextArea" width="100%" height="100%" text="{data}">
+
+ </s:TextArea>
+ </s:Panel>
+ </fx:Component>
+ </fx:Declarations>
+
+ <s:HGroup width="100%"
+ left="5" right="5"
+ verticalAlign="middle"
+ typographicCase="lowercaseToSmallCaps">
+
+ <s:Label id="generateLabel"
+ text="Show Changes"
+ textAlign="center"
+ buttonMode="true"
+ backgroundColor="#484848"
+ color="#eeeeee"
+ fontWeight="bold"
+ fontSize="10"
+ paddingBottom="4" paddingLeft="4"
+ paddingRight="4" paddingTop="4"
+ minWidth="{generateLabel.height}" />
+
+ <s:Label id="exportLabel"
+ text="Export"
+ textAlign="center"
+ buttonMode="true"
+ backgroundColor="#484848"
+ color="#eeeeee"
+ fontWeight="bold"
+ fontSize="10"
+ paddingLeft="4"
+ paddingBottom="4"
+ paddingRight="4"
+ paddingTop="4"
+ minWidth="{exportLabel.height}"
+ visible="{Boolean(xml)}"
+ includeInLayout="{Boolean(xml)}"
+ />
+
+ <s:Spacer width="100%"/>
+
+ <controls:ImageButton id="copyIcon"
+ source="{Radii8LibraryAssets.copy}"
+ toolTip="Copy the changes to the Clipboard"/>
+
+ </s:HGroup>
+
+</s:Group>
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/views/Description.mxml
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/views/Description.mxml b/Radii8Library/src/com/flexcapacitor/views/Description.mxml
new file mode 100644
index 0000000..89dee61
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/views/Description.mxml
@@ -0,0 +1,260 @@
+<?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="100%"
+ xmlns:controls="com.flexcapacitor.controls.*"
+ creationComplete="group2_creationCompleteHandler(event)">
+
+ <fx:Script>
+ <![CDATA[
+ import com.flexcapacitor.controller.Radiate;
+ import com.flexcapacitor.events.InspectorEvent;
+ import com.flexcapacitor.events.RadiateEvent;
+ import com.flexcapacitor.utils.InspectorUtils;
+
+ import mx.core.UIComponent;
+ import mx.events.FlexEvent;
+
+ [Bindable]
+ public var showIcon:Boolean = true;
+
+ [Bindable]
+ public var showCopyIcon:Boolean;
+
+ [Bindable]
+ public var showDescriptionLabel:Boolean = true;
+
+ public var describedType:XML;
+
+ [Bindable]
+ public var selectedItemClass:String;
+
+ [Bindable]
+ public var selectedItemQualifiedClass:String;
+
+ [Bindable]
+ public var selectedItemDescription:String;
+
+ [Bindable]
+ public var selectedItemPackage:String;
+
+ [Bindable]
+ public var selectedItemName:String;
+
+ [Bindable]
+ public var selectedItemID:String;
+
+ [Bindable]
+ public var selectedItemSuperClass:String;
+
+ [Bindable]
+ public var selectedItemSuperClassPackage:String;
+
+ [Bindable]
+ public var selectedItemDocument:String;
+
+ [Bindable]
+ public var selectedItemParentDocument:String;
+
+ /**
+ * A list of attributes that can be displayed and their order.
+ * Items are "normal", "id", "name", "class", "superClass", "document", "package", "parentDocument"
+ * */
+ [Bindable]
+ public var includedItems:Array = ["normal","id","name","class","superClass","document","package","parentDocument"];
+
+ private var _target:Object;
+
+ public function get target():Object {
+ if (_target==null) return "";
+ return _target;
+ }
+
+ /**
+ * This is set automatically when a new target is selected
+ * This can be any type. You must disable this component if the
+ * type is not what you can process.
+ * */
+ [Bindable]
+ public function set target(value:Object):void {
+
+ // the target
+ if (value==null) {
+ _target = null;
+ selectedItemDescription = "No Selection";
+ enabled = false;
+ return;
+ }
+ else {
+ enabled = true;
+ }
+
+ _target = value;
+
+ var parentName:String = target is UIComponent ? InspectorUtils.getClassName(UIComponent(target).parentDocument) : "";
+
+ // description of target
+ selectedItemQualifiedClass = InspectorUtils.getQualifiedClassName(target);
+ selectedItemClass = InspectorUtils.getClassName(target);
+ selectedItemName = InspectorUtils.getName(target);
+ selectedItemID = InspectorUtils.getIdentifier(target) || "";
+ selectedItemSuperClass = InspectorUtils.getSuperClassName(target);
+ selectedItemSuperClassPackage = InspectorUtils.getSuperClassPackage(target);
+ selectedItemPackage = InspectorUtils.getPackageName(target);
+ selectedItemParentDocument = InspectorUtils.getParentDocumentName(target) || "";
+ selectedItemDocument = InspectorUtils.getDocumentName(target) || "";
+
+ // example, if ID exists, "myButtonID:Button in MyComponent"
+ // if ID isn't set, "Button0 in MyComponent"
+ selectedItemDescription = target ? (selectedItemID ? selectedItemClass + "." + selectedItemID : selectedItemClass) + " in " + selectedItemDocument : "";
+
+ if (selectedItemDescription.indexOf("null")!=-1) {
+ selectedItemDescription = selectedItemClass ? selectedItemClass : "";
+ }
+ }
+
+ /**
+ * Notify host components when we change the target
+ * */
+ public function changeTarget(newTarget:Object):void {
+ var selectionChangeEvent:InspectorEvent = new InspectorEvent(InspectorEvent.CHANGE);
+ selectionChangeEvent.targetItem = newTarget;
+ dispatchEvent(selectionChangeEvent);
+ }
+
+ /**
+ * Go to the next state
+ * */
+ protected function group1_clickHandler(event:MouseEvent):void {
+ var selectedStateIndex:int = includedItems.indexOf(currentState);
+
+ if (selectedStateIndex==-1 || selectedStateIndex + 1==includedItems.length) {
+ currentState = includedItems.length>0 ? includedItems[0] : "";
+ }
+ else {
+ currentState = includedItems[selectedStateIndex+1];
+ }
+
+ }
+
+ /**
+ * Copies the value displayed to the clipboard
+ * */
+ public function copySelectedValue():void {
+ InspectorUtils.copyToClipboard(descriptionTextValue.text);
+ }
+
+ public var radiate:Radiate = Radiate.instance;
+
+ protected function group2_creationCompleteHandler(event:FlexEvent):void {
+ radiate.addEventListener(RadiateEvent.TARGET_CHANGE, targetChangeHandler);
+ }
+
+ protected function targetChangeHandler(event:RadiateEvent):void {
+ target = event.selectedItem;
+ }
+
+ ]]>
+ </fx:Script>
+
+ <fx:Declarations>
+ <!-- Place non-visual elements (e.g., services, value objects) here -->
+ </fx:Declarations>
+
+ <s:states>
+ <s:State name="normal"/>
+ <s:State name="class"/>
+ <s:State name="qualifiedClass"/>
+ <s:State name="id"/>
+ <s:State name="name"/>
+ <s:State name="superClass"/>
+ <s:State name="document"/>
+ <s:State name="package"/>
+ <s:State name="parentDocument"/>
+ </s:states>
+
+ <s:HGroup width="100%" verticalAlign="middle">
+ <s:Image source="{Radii8LibraryAssets.componentIcon}"
+ height="16"
+ width="16"
+ source.document="{Radii8LibraryAssets.componentIcon}"
+ includeInLayout="{showIcon}"
+ source.package="{Radii8LibraryAssets.packageIcon}"
+ visible="{showIcon}"
+ useHandCursor="true"
+ mouseChildren="false"
+ buttonMode="true"
+ toolTip="The document that contains this item"/>
+
+ <s:Label id="descriptionTextName" paddingTop="4"
+ minWidth="50"
+ color="#2F3030" fontWeight="bold"
+ includeInLayout="{showDescriptionLabel}"
+ visible="{showDescriptionLabel}"
+ text.normal=""
+ text.class="Class:"
+ text.id="ID: "
+ text.name="Name:"
+ text.document="Document:"
+ text.package="Package:"
+ text.parentDocument="Parent Document:"
+ text.superClass="Super Class:"
+ useHandCursor="true"
+ mouseChildren="false"
+ buttonMode="true"
+ click="group1_clickHandler(event)"/>
+
+ <s:RichText id="descriptionTextValue"
+ width="100%"
+ paddingTop="4"
+ maxDisplayedLines="1"
+ color="#2F3030" fontWeight="normal"
+ text.normal="{selectedItemDescription}"
+ text.class="{selectedItemClass}"
+ text.id="{selectedItemID}"
+ text.name="{selectedItemName}"
+ text.superClass="{selectedItemSuperClass}"
+ text.document="{selectedItemDocument}"
+ text.package="{selectedItemPackage}"
+ text.parentDocument="{selectedItemParentDocument}"
+ />
+ <mx:UIComponent width="100%"
+ includeInLayout="{showCopyIcon}"
+ visible="{showCopyIcon}"/>
+ <s:Image source="{Radii8LibraryAssets.copy}" height="16" width="16"
+ includeInLayout="{showCopyIcon}"
+ visible="{showCopyIcon}"
+ useHandCursor="true" mouseChildren="false" buttonMode="true"
+ click="copySelectedValue()"
+ toolTip="Copy the text to the clipboard"/>
+
+ </s:HGroup>
+
+ <s:Group width="100%" height="100%"
+ click="group1_clickHandler(event)" >
+ <s:Rect width="100%" height="100%" >
+ <s:fill>
+ <s:SolidColor color="0" alpha="0"/>
+ </s:fill>
+ </s:Rect>
+ </s:Group>
+</s:Group>