RichTextEditor源文件

<?xml version="1.0"?>

<!--

 ADOBE SYSTEMS INCORPORATED
 Copyright 2005-2007 Adobe Systems Incorporated
 All Rights Reserved.

 NOTICE: Adobe permits you to use, modify, and distribute this file
 in accordance with the terms of the license agreement accompanying it.

-->

<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" minWidth="220" minHeight="200" width="325" height="300">

 <mx:Metadata>

  [Event(name="change", type="flash.events.Event")]
  
  [DefaultTriggerEvent("change")]
  
  /**
   *  Name of the CSS Style declaration to use for the styles for the TextArea.
   *  By default, the TextArea uses the RichTextEditor control's inheritable styles.
   */
  [Style(name="textAreaStyleName", type="String", inherit="no")]
  
  [IconFile("RichTextEditor.png")]
  
  [Exclude(name="alignButtons", kind="property")]
  [Exclude(name="boldButton", kind="property")]
  [Exclude(name="bulletButton", kind="property")]
  [Exclude(name="colorPicker", kind="property")]
  [Exclude(name="defaultButton", kind="property")]
  [Exclude(name="fontFamilyArray", kind="property")]
  [Exclude(name="fontFamilyCombo", kind="property")]
  [Exclude(name="fontSizeArray", kind="property")]
  [Exclude(name="fontSizeCombo", kind="property")]
  [Exclude(name="icon", kind="property")]
  [Exclude(name="italicButton", kind="property")]
  [Exclude(name="label", kind="property")]
  [Exclude(name="layout", kind="property")]
  [Exclude(name="linkTextInput", kind="property")]
  [Exclude(name="toolBar", kind="property")]
  [Exclude(name="toolBar2", kind="property")]
  [Exclude(name="underlineButton", kind="property")]

 </mx:Metadata>

 <mx:Array id="fontFamilyArray">
  <mx:String>_sans</mx:String>
  <mx:String>_serif</mx:String>
  <mx:String>_typewriter</mx:String>
  <mx:String>Arial</mx:String>
  <mx:String>Courier</mx:String>
  <mx:String>Courier New</mx:String>
  <mx:String>Geneva</mx:String>
  <mx:String>Georgia</mx:String>
  <mx:String>Helvetica</mx:String>
  <mx:String>Times New Roman</mx:String>
  <mx:String>Times</mx:String>
  <mx:String>Verdana</mx:String>
 </mx:Array>

 <mx:Array id="fontSizeArray">
  <mx:String>8</mx:String>
  <mx:String>9</mx:String>
  <mx:String>10</mx:String>
  <mx:String>11</mx:String>
  <mx:String>12</mx:String>
  <mx:String>14</mx:String>
  <mx:String>16</mx:String>
  <mx:String>18</mx:String>
  <mx:String>20</mx:String>
  <mx:String>22</mx:String>
  <mx:String>24</mx:String>
  <mx:String>26</mx:String>
  <mx:String>28</mx:String>
  <mx:String>36</mx:String>
  <mx:String>48</mx:String>
  <mx:String>72</mx:String>
 </mx:Array>

 <mx:Script>
 <![CDATA[
 
 import mx.controls.textClasses.TextRange;
 import mx.core.mx_internal;
    import mx.core.IUITextField;
    import mx.core.UITextFormat;

 use namespace mx_internal;
 
 public var fontFamilyToolTip:String = "Font Family";
 public var fontSizeToolTip:String = "Font Size";
 public var boldToolTip:String = "Bold";
 public var italicToolTip:String = "Italic";
 public var underlineToolTip:String = "Underline";
 public var colorPickerToolTip:String = "Color";
 public var alignToolTip:String = "Align";
 public var bulletToolTip:String = "Bullet";
 public var linkToolTip:String = "Link";

 private var linkTextCommitted:Boolean = false;
 private var showControlBarChanged:Boolean = false;
 private var showToolTipsChanged:Boolean = false;
 private var textChanged:Boolean = false;
 private var htmlTextChanged:Boolean = false;
 private var previousTextFormat:TextFormat = null;
 private var textFormatChanged:Boolean = false;
 // -1 is used to force updation of the ToolBar styles
 private var lastCaretIndex:int = -1;
 private var invalidateToolBarFlag:Boolean = false;
 private var firstTime:Boolean = true;
 
 /*
 public function RichTextEditor()
 {
  super();
 }
 */
 
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  defaultLinkProtocol
    //----------------------------------

 private var _defaultLinkProtocol:String = "http://";

 [Inspectable(defaultValue="http://")]
 
 public function get defaultLinkProtocol():String
 {
  return _defaultLinkProtocol;
 }

 public function set defaultLinkProtocol(value:String):void
 {
  _defaultLinkProtocol = value;
  
  if (linkTextInput)
   linkTextInput.text = _defaultLinkProtocol;
 }

    //----------------------------------
    //  showControlBar
    //----------------------------------

 private var _showControlBar:Boolean = true;

 [Inspectable(category="General", defaultValue="true")]
 
 public function get showControlBar():Boolean
 {
  return _showControlBar;
 }

 public function set showControlBar(value:Boolean):void
 {
  _showControlBar = value;
  showControlBarChanged = true;
  invalidateProperties();
 }

    //----------------------------------
    //  showToolTips
    //----------------------------------

 private var _showToolTips:Boolean = false;

 [Inspectable(defaultValue="false")]
 
 public function get showToolTips():Boolean
 {
  return _showToolTips;
 }

 public function set showToolTips(value:Boolean):void
 {
  _showToolTips = value;
  showToolTipsChanged = true;
  invalidateProperties();
 }

    //----------------------------------
    //  selection
    //----------------------------------

 /**
     *  The selected text.
     */
 public function get selection():TextRange
 {
  return new TextRange(this, true);
 }

    //----------------------------------
    //  text
    //----------------------------------

 private var _text:String = "";

 [Bindable("valueCommit")]
 [CollapseWhiteSpace]
 [NonCommittingChangeEvent("change")]
 [Inspectable(category="General")]

 public function get text():String
 {
  return textArea ? textArea.text : _text;
 }

 public function set text(value:String):void
 {
  _text = value;
  textChanged = true;
  invalidateProperties();
 }

    //----------------------------------
    //  htmlText
    //----------------------------------

 private var _htmlText:String = "";

 [Bindable("valueCommit")]
 [CollapseWhiteSpace]
 [NonCommittingChangeEvent("change")]
 [Inspectable(category="General")]

 public function get htmlText():String
 {
  return textArea ? textArea.htmlText : _htmlText;
 }

 public function set htmlText(value:String):void
 {
  _htmlText = value;
  htmlTextChanged = true;
  invalidateProperties();
 }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

 override protected function commitProperties():void
 {
  super.commitProperties();

  if (firstTime)
  {
   firstTime = false;
   var textAreaStyleName:String = getStyle(
        "textAreaStyleName");
   if (textAreaStyleName)
    textArea.styleName = textAreaStyleName;
   textArea.getTextField().alwaysShowSelection = true;
  }
  
  if (showControlBarChanged)
  {
   if (_showControlBar)
   {
    controlBar.height = NaN;
    controlBar.visible = true;
   }
   else
   {
    controlBar.height = 0;
    controlBar.visible = false;
   }
   showControlBarChanged = false;
  }
     
  if (showToolTipsChanged)
  {
   if (_showToolTips)
   {
    fontFamilyCombo.toolTip = fontFamilyToolTip;
    fontSizeCombo.toolTip = fontSizeToolTip;
    boldButton.toolTip = boldToolTip;
    italicButton.toolTip = italicToolTip;
    underlineButton.toolTip = underlineToolTip;
    colorPicker.toolTip = colorPickerToolTip;
    alignButtons.toolTip = alignToolTip;
    bulletButton.toolTip = bulletToolTip;
    linkTextInput.toolTip = linkToolTip;
   }
   else
   {
    fontFamilyCombo.toolTip = "";
    fontSizeCombo.toolTip = "";
    boldButton.toolTip = "";
    italicButton.toolTip = "";
    underlineButton.toolTip = "";
    colorPicker.toolTip = "";
    alignButtons.toolTip = "";
    bulletButton.toolTip = "";
    linkTextInput.toolTip = "";
   } 
   showToolTipsChanged = false;
  }
  
  if (textChanged || htmlTextChanged)
  {
   // Revert previously set TextFormat.
   var tf:UITextFormat = IUITextField(textArea.getTextField()).getUITextFormat();
   // bullet style is not exposed in flex
   // hence has to be explicitly defaulted.
   tf.bullet = false;
   textArea.getTextField().defaultTextFormat = tf;
   if (textChanged)
   {
    if (_text !== null)
     textArea.text = _text;
    textChanged = false;
   }
   else
   {
    if (_htmlText !== null)
     textArea.htmlText = _htmlText;
    htmlTextChanged = false;
   }
  }
 }
 
 override protected function measure():void
 {
  // Called only when explicitWidth and
  // explicitHeight are set to NaN, since
  // we have set width and height explicitly
  // for RTE's panel.
  super.measure();
  measuredMinWidth = 220;
  measuredWidth = 320;
  measuredMinHeight = 200;
  measuredHeight = 300;
 }

 /**
  *  @private
  */
 override public function styleChanged(styleProp:String):void
 {
  super.styleChanged(styleProp);

  if (styleProp == null || styleProp == "textAreaStyleName")
  {
   if (textArea)
   {
    var textAreaStyleName:String = getStyle("textAreaStyleName");
    textArea.styleName = textAreaStyleName;
   }
  }
  
  if (!invalidateToolBarFlag)
  {
   invalidateToolBarFlag = true;
   callLater(getTextStyles);
  }
 }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

 private function setTextStyles(type:String, value:Object = null):void
 {
  var tf:TextFormat;

  var beginIndex:int = textArea.getTextField().selectionBeginIndex;
  var endIndex:int = textArea.getTextField().selectionEndIndex;

  if (beginIndex == endIndex)
  {
   tf = previousTextFormat;
  }
  else 
   tf = new TextFormat();
  
  if (type == "bold" || type == "italic" || type == "underline")
  {
   tf[type] = value;
  }
  else if (type == "align" || type == "bullet")
  {
   if (beginIndex == endIndex)
   {
    tf = new TextFormat();
   }

   // Apply the paragraph styles to the whole paragraph instead of just
   // the selected text
   beginIndex = textArea.getTextField().getFirstCharInParagraph(beginIndex) - 1;
   beginIndex = Math.max(0, beginIndex);
   endIndex = textArea.getTextField().getFirstCharInParagraph(endIndex) +
    textArea.getTextField().getParagraphLength(endIndex) - 1;
   tf[type] = value;
   previousTextFormat[type] = value;
   if (!endIndex)
    textArea.getTextField().defaultTextFormat = tf;
  }
  else if (type == "font")
  {
   tf[type] = fontFamilyCombo.text;
  }
  else if (type == "size")
  {
   var fontSize:uint = uint(fontSizeCombo.text);
   if (fontSize > 0)
    tf[type] = fontSize;
  }
  else if (type == "color")
  {
   tf[type] = uint(colorPicker.selectedColor);
  }
  else if (type == "url")
  {
   if (value != defaultLinkProtocol && value != "")
   {
    tf[type] = value;
    tf["target"] = "_blank";
   }
   else if (tf[type] != "")
   {
    tf[type] = "";
    tf["target"] = "";
   }
  }

  textFormatChanged = true;
    
  if (beginIndex == endIndex)
  {
   previousTextFormat = tf;
  }
  else
  {
   textArea.getTextField().setTextFormat(tf,beginIndex,endIndex);
  }

  dispatchEvent(new Event("change"));
  
  var caretIndex:int = textArea.getTextField().caretIndex;
  var lineIndex:int = textArea.getTextField().getLineIndexOfChar(caretIndex);

  textArea.invalidateDisplayList();
  textArea.validateDisplayList();

  // Scroll to make the line containing the caret under viewable area
  while (lineIndex >= textArea.getTextField().bottomScrollV)
  {
   textArea.verticalScrollPosition++;
  }

  callLater(textArea.setFocus);
 }

 private function getTextStyles():void
 {
  if (!textArea)
   return;
   
  var tf:TextFormat;

  var beginIndex:int = textArea.getTextField().selectionBeginIndex;
  var endIndex:int = textArea.getTextField().selectionEndIndex;

  if (beginIndex == endIndex)
   linkTextInput.enabled = false;
  else
   linkTextInput.enabled = true; 
   
  if (textFormatChanged)
   previousTextFormat = null;

  if (beginIndex == endIndex)
  {
   tf = textArea.getTextField().defaultTextFormat;
   if (tf.url != "")
   {
    var carIndex:int = textArea.getTextField().caretIndex;
    if (carIndex < textArea.getTextField().length)
    {
     var tfNext:TextFormat=textArea.getTextField().getTextFormat(carIndex, carIndex + 1);
     if (!tfNext.url || tfNext.url == "")
      tf.url = tf.target = "";
    }
    else
     tf.url = tf.target = "";
   }
  }
  else
   tf = textArea.getTextField().getTextFormat(beginIndex,endIndex);

  if (!previousTextFormat || previousTextFormat.font != tf.font)
   setComboSelection(fontFamilyCombo, tf.font ? tf.font : "");
  if (!previousTextFormat || previousTextFormat.size != tf.size)
   setComboSelection(fontSizeCombo, tf.size ? String(tf.size) : "");
  if (!previousTextFormat || previousTextFormat.color != tf.color)
   colorPicker.selectedColor = Number(tf.color);
  
  if (!previousTextFormat || previousTextFormat.bold != tf.bold)
   boldButton.selected = tf.bold;
  if (!previousTextFormat || previousTextFormat.italic != tf.italic)
   italicButton.selected = tf.italic;
  if (!previousTextFormat || previousTextFormat.underline != tf.underline)
   underlineButton.selected = tf.underline;

  if (!previousTextFormat || previousTextFormat.align != tf.align)
  {
   if (tf.align == "left")
    alignButtons.selectedIndex = 0;
   else if (tf.align == "center")
    alignButtons.selectedIndex = 1;
   else if (tf.align == "right")
    alignButtons.selectedIndex = 2;
   else if (tf.align == "justify")
    alignButtons.selectedIndex = 3;
  }
  if (!previousTextFormat || previousTextFormat.bullet != tf.bullet)
   bulletButton.selected = tf.bullet;
  if (!previousTextFormat || previousTextFormat.url != tf.url)
   linkTextInput.text = (tf.url == "" || tf.url == null) ? defaultLinkProtocol : tf.url;
  
  if (textArea.getTextField().defaultTextFormat != tf)
   textArea.getTextField().defaultTextFormat = tf;
  previousTextFormat = tf;
  textFormatChanged = false;
  
  lastCaretIndex = textArea.getTextField().caretIndex;
  invalidateToolBarFlag = false;
 }

 private function setComboSelection(combo:ComboBox,val:String):void
 {
  var length:uint = combo.dataProvider.length;
  
  for (var i:uint = 0; i < length; i++)
  {
   if (combo.dataProvider.getItemAt(i).toLowerCase() == val.toLowerCase())
   {
    combo.selectedIndex = i;
    return;
   }
  }
  combo.selectedIndex = -1;
  combo.validateNow();
  combo.text = val;
 }

 /**
  *  @private
  *  This method is called when the user clicks on the textArea, drags
  *  out of it and releases the mouse button outside the TextArea.
  */
 private function systemManager_mouseUpHandler(event:MouseEvent):void
 {
  if (lastCaretIndex != textArea.getTextField().caretIndex)
   getTextStyles();
  else
  {
   if (textArea.getTextField().selectionBeginIndex == textArea.getTextField().selectionEndIndex)
    linkTextInput.enabled = false;
   else
    linkTextInput.enabled = true; 
  }
  systemManager.removeEventListener(
   MouseEvent.MOUSE_UP, systemManager_mouseUpHandler, true);  
 }
 
 ]]>
 </mx:Script>

 <mx:TextArea id="textArea" height="100%" width="100%" minHeight="0" minWidth="0"
     change="dispatchEvent(event);"
     valueCommit="dispatchEvent(event);"
     keyUp="getTextStyles()"
     keyDown="if (textFormatChanged)
      {
       textArea.getTextField().defaultTextFormat=previousTextFormat;
       textFormatChanged = false;
      }"
     mouseDown="systemManager.addEventListener(
     MouseEvent.MOUSE_UP, systemManager_mouseUpHandler, true);"
     />

 <mx:ControlBar>

  <mx:ToolBar id="toolbar" width="100%" horizontalGap="7">
   
   <mx:ComboBox id="fontFamilyCombo" editable="true"
    creationComplete="getTextStyles();lastCaretIndex = -1;"
    dataProvider = "{fontFamilyArray}"
    close="setTextStyles('font');"
    enter="setTextStyles('font');"/>

   <mx:ComboBox id="fontSizeCombo" editable="true"
    paddingLeft="2" paddingRight="2"
    dataProvider = "{fontSizeArray}"
    close="setTextStyles('size');"
    enter="setTextStyles('size');"/>
     
   <mx:HBox id="toolBar2" horizontalGap="0">

    <mx:Button id="boldButton" width="20" toggle="true"
         icon="@Embed('assets/icon_style_bold.png')"
         click="setTextStyles('bold', event.currentTarget.selected);" />
    
    <mx:Button id="italicButton" width="20" toggle="true"
         icon="@Embed('assets/icon_style_italic.png')"
         click="setTextStyles('italic', event.currentTarget.selected);" />
    
    <mx:Button id="underlineButton" width="20" toggle="true"
         icon="@Embed('assets/icon_style_underline.png')"
         click="setTextStyles('underline', event.currentTarget.selected);" />

   </mx:HBox>
  
   <mx:ColorPicker id="colorPicker" width="22" height="22"
      close="setTextStyles('color');"/>

   <mx:VRule height="{alignButtons.height}"/>

   <mx:ToggleButtonBar id="alignButtons" buttonWidth="20"
       itemClick="setTextStyles('align', ToggleButtonBar(event.currentTarget).dataProvider.getItemAt(ToggleButtonBar(event.currentTarget).selectedIndex).action); " >
    <mx:dataProvider>
     <mx:Array>
      <mx:Object icon="@Embed('assets/icon_align_left.png')" action="left"/>
      <mx:Object icon="@Embed('assets/icon_align_center.png')" action="center"/>
      <mx:Object icon="@Embed('assets/icon_align_right.png')" action="right"/>
      <mx:Object icon="@Embed('assets/icon_align_justify.png')" action="justify"/>
     </mx:Array>
    </mx:dataProvider>
   </mx:ToggleButtonBar>

   <mx:Button id="bulletButton" width="20" toggle="true"
       icon="@Embed('assets/icon_bullet.png')"
       click="setTextStyles('bullet', event.currentTarget.selected);" />

   <mx:VRule height="{linkTextInput.height}"/>

   <mx:TextInput id="linkTextInput" width="140"
    focusOut="if (linkTextCommitted)
        { trace('already committed'); linkTextCommitted = false; }
        else
        { trace('not committed'); setTextStyles('url', linkTextInput.text); linkTextInput.text=defaultLinkProtocol;}"
    enter="setTextStyles('url', linkTextInput.text); linkTextInput.text = defaultLinkProtocol; linkTextCommitted = true;"/>

  </mx:ToolBar>

 </mx:ControlBar>

</mx:Panel>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值