2008
04.19


Описание проблемы:

Если вы хотите чтобы ссылки, включенные в текстовые блоки, были активными, свойство selectable должно принимать значение true. Иногда это сбивает с толку пользователей.

Решение:

Создание собственного компонента LinkTextArea, расширяющего TextArea, который будет рассылать соответствующе событие link.

Объяснение:

Выходом их этой ситуации является создание компонента LinkTextArea, расширяющего TextArea. Переопределяя функцию set selectable, мы можем добавть обработчик событий, чтоб отлавливать все клики в TextArea. Наш onClick обработчик будет брать свойство url (если оно есть) и рассылать событие link.

Т.к. мы переопределяем функцию set selectable, то можем вызывать наш обработчик в случае, когда свойство selectable равно true, и переставать вызывать его, когда selectable равно false. Таким образом мы не повлияем на функциональность TextArea когда свойство selectable = true.

Наш onClick обработчик:

1. Определяет символ в месте где щёлкнули мышкой;
2. Определяет TextRange состоящей из этого символа;
3. Берет свойство url нашего TextRange (если оно определенно);
4. Если определенно, парсим урл и добавляем его к событию flash.events.TextEvent.LINK, которое мы рассылаем при помощи вызова dispatchEvent.

ПРИМЕЧАНИЕ: когда url является событием, Флэш автоматически отрезает "event:" часть ссылки перед рассылкой события. Чтобы сохранить совместимость, нам надо вручную удалять ее перед рассылкой сообщения.

Код:

package com.robsheely.text
{
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.events.TextEvent;
  import mx.core.mx_internal;
  import mx.core.UITextField;
  import mx.controls.TextArea;
  import mx.controls.textClasses.TextRange;
  import mx.events.FlexEvent;

  use namespace mx_internal;
   
  public class LinkTextArea extends TextArea
  {
    public function LinkTextArea()
    {
      super();
      addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
    }
   
    protected function onCreationComplete(pEvent:FlexEvent):void
    {
      selectable = false;
    }

    // Переопределяем свойство selectable так, чтоб мы могли добавлять наш
    // обработчик onClick когда selectable установленно в true, либо удалять
    // обработчик, если selectable равно false - позволяя таким образом
    // нормально работать стандартным обработчикам.
    override public function set selectable(pSelectable:Boolean):void
    {
      super.selectable = pSelectable;
      if (textField)
      {
        textField.selectable = pSelectable;
      }
      else
      {
        // Если мы пытаемся установить значение свойству selectable до того как
        // компонент проинициализируется, то нам надо отложить передачу команды
        // текстовому полю (которое пока ещё не создалось) до тех пор, пока
        // не будет завершенна инициализация.
        callLater(function(pSelectable:Boolean):void
        {
          textField.selectable = pSelectable;
        }, [pSelectable]);
      }
      if (!pSelectable)
      {
        addEventListener(MouseEvent.CLICK, onClick);
      }
      else
      {
        UITextField(textField).setSelection(-1, -1);
        removeEventListener(MouseEvent.CLICK, onClick);
      }
    }

    protected function onClick(pEvent:MouseEvent):void
    {
      // Находим букву по коорой кликнули мышкой
      var index:int = textField.getCharIndexAtPoint(pEvent.localX, pEvent.localY);
      if (index != -1)
      {
        // преобразуем букву к TextRange, чтобы иметь возможность
        // извлечь свойство url
        var range:TextRange = new TextRange(this, false, index, index + 1);
        // убеждаемся что TextRange содержит url
        if (range.url.length > 0)
        {
          // Стандартный clickEvent отрезает "event:" подстроку свойства url.
          // Для сохранения совместимости тоже отрежем "event:"
          var url:String = range.url;
          if (url.substr(0, 6) == 'event:')
          {
            url = url.substring(6);
          }
          // Рассылаем событие "link" с адресом ссылки в теле события
          dispatchEvent(new TextEvent(TextEvent.LINK, false, false, url));
        }
      }
    }
  }
}

Скачать пример

Оригинал: Make Text Area Links Active Without Making Text Selectable

Перевод: WD479


google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

557 comments so far

Add Your Comment