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