воскресенье, марта 22, 2009

mx:Pause vs flash.utils.Timer. Flex

Декларативность MXML - огромное достоинство Flex.
Легкое определение переменных в MXML значительно упрощает разработку:
  • позволяет легко и наглядно определять их свойства и обработчики событий
  • автоматически делает переменные Bindable
  • позволяет их связать с другими переменными и выражениями
  • делает наглядным код

Но, на сколько я понял, не все классы можно представить в декларативном виде.

Например, класс flash.utils.Timer невозможно представить в виде MXML. Компилятор выдает ошибку "Неправильное количество аргументов". Всё от того, что конструктор этого класса содержит один обязательный параметр. Как его указать, и возможно ли это, увы, я не понял.

Но есть простое решение - использовать другой класс, хорошо подходящий по своему функционалу - mx.effects.Pause:

<mx:Pause
id="somePause"
duration="2000"
effectEnd="somePause_effectEndHandler(event)"
/>

. . .

//Стартовать задержку
this.somePause.play();

. . .

private function somePause_effectEndHandler(event:EffectEvent):void {
//Обработать окончание задержки
}

четверг, марта 19, 2009

ASDoc in MXML. Правильно комментируем MXML.

MXML для Flex-разработки имеет первостепенное значение. Однако, воспринимая его как порождение XML, до некоторых пор, я не считал его языком программирования или чем-то в этом духе.
Теперь, уже достаточно сроднившись с MXML, понимаю, что есть необходимость правильно его комментировать. Просматривая листинги MXML, глаз так же нуждается в разделении блоков, как и при чтении AS-кода.
Если с AS-кодом всё давно ясно (я его использую везде где надо и где необязательно), то вот с MXML хотелось бы разобраться. И поможет нам в этом статейка "ASDoc in MXML - Functional and Design Specification". Выделим основные мысли из нее.

Основные положения

В настоящее время не существует способа документировать MXML-компоненты. (Кстати, в лайфдоках про это вот что сказано: Documenting MXML files). Компилятор asdoc не обрабатывает комментарии в MXML-файлах. Но число компонентов, разрабатываемых на базе MXML неуклонно растет, поэтому поддержка в asdoc файлов MXML очень бы помогла разработчикам при создании документации.

ASDoc комментарий

Для того, чтобы ASDoc-комментарий был обработан asdoc-компилятором, необходимо указать 3 тире после <!:
<!--- asdoc comment -->
Для сравнения - обычный комментарий начинается с 2-х тире.

Комментирование MXML-компонентов и компонента уровня класса

Комментарии для компонентов внутри MXML должны располагаться перед компонентами.
Комментарий компонента уровня класса должен располагаться перед корневым тегом MXML:

<?xml version="1.0"?>

<!-- Standard MXML comment: events\myComponents\MyButton.mxml -->

<!---
The class level comment for the component.
This tag supports all ASDoc tags, and does not require a CDATA block.

@see mx.container.VBox
-->
<mx:VBox xmlns="http://ns.adobe.com/mxml/2009" xmlns:mx="library:adobe/flex/halo" >

<!--- Comment for button -->
<mx:Button id="myButton" label="This button has comment"/>

<!--- This comment doesn't belong to any component and will be ignored -->

</mx:VBox>

Комментарии перед тегами Script, Metadata будут игнорироваться. Перед тегами Definition, Library, Private и внутри их, комментарии так же будут игнорироваться.

Итог

В статье приводятся примеры использования ASDoc комментирования в различных его применениях. Рассматривать их подробно я не буду - всё достаточно прозрачно.

Вывод таков - MXML комментировать надо. И для этого уже существует прототип (если я правильно понял) стандарта, которого и следует придерживаться.

четверг, марта 05, 2009

Дружим Flex с Flash. Заметки: загрузка, внедрение, шрифт. Flex

Закончился очередной дидлайн. После крупных проектов, которые делаются за 3-4 дня практически с нуля, остаются ощущения, схожие с состоянием после автобусного тура: в голове каша, мельком что-то увидел, урывками что-то запомнил, надо разобрать фотки. Теперь настало время немного отдышаться и закрепить полученный опыт.

Для начала, несколько заметок:

  • Перенос строки в строках MXML: символ &#xd; - мелочь, а приятно.
  • Загрузка сложных Flash-приложений в SWFLoader должна производиться в выделенный домен приложения, т.к. могут быть конфликты классов:
<mx:SWFLoader autoLoad="false" id="swfLoader" source="application.swf" />

. . .

private function creationCompleteHandler(event:Event):void {
swfLoader.loaderContext=new LoaderContext(false,new ApplicationDomain());
swfLoader.load();
}
  • Если внешнее приложение подгружается в SWFLoader, есть вероятность, что в какой-то момент SWFLoader потеряет stage, что может пагубно отразиться на функциональности этого приложения. Если приложение где-то внутри обращается к stage и не обрабатывает его недоступность, то будут генерироваться ошибки. Побороть этот недостаток я не смог - только устранив все "не защищенные" stage из внешнего приложения.
  • Внедрение шрифтов. Гораздо надежнее внедрять шрифт непосредственно из TTF файла. Внедрение из файла SWF, в котором, в свою очередь, внедрен необходимый шрифт лучше оставить для тяжелых случаев несовместимостей с Flex. Дело в том, что почему-то, внедренные в SWF разные стили (normal, bold) шрифта не корректно "извлекаются" Flex-ом. Он не дает назвать разные стили разными именами (как это можно сделать в первом случае), теряет одно из начертаний (жирный шрифт просто не выводится). Возможно, это из-за особенностей конкретных шрифтов, но первый метод срабатывает гораздо стабильнее.
@font-face
{
fontFamily: "Century Schoolbook";
fontWeight: normal;
fontStyle: normal;
src: url("file://./assets/fonts/CENSCBK.TTF");
unicodeRange:
U+0020-U+0040, /* Punctuation, Numbers */
U+0041-U+005A, /* Upper-Case A-Z */
U+005B-U+0060, /* Punctuation and Symbols */
U+0061-U+007A, /* Lower-Case a-z */
U+007B-U+007E, /* Punctuation and Symbols */
U+00FC-U+00FD,
U+0410-U+042F, /* Cyrillic Upper-Case A-Z */
U+0430-U+0451; /* Cyrillic Lower-Case a-z */
}

@font-face
{
fontFamily: "Century Schoolbook Bold";
fontWeight: bold;
fontStyle: normal;
src: url("file://./assets/fonts/SCHLBKB.TTF");
unicodeRange:
U+0020-U+0040, /* Punctuation, Numbers */
U+0041-U+005A, /* Upper-Case A-Z */
U+005B-U+0060, /* Punctuation and Symbols */
U+0061-U+007A, /* Lower-Case a-z */
U+007B-U+007E, /* Punctuation and Symbols */
U+00FC-U+00FD,
U+0410-U+042F, /* Cyrillic Upper-Case A-Z */
U+0430-U+0451; /* Cyrillic Lower-Case a-z */
}


  • Внедрять клип из внешней SWF так, чтобы работали его фреймовые скрипты можно следующим образом:
    source="@Embed(source='assets/Index.swf')"
    При внедрении отдельного символа, его фреймовые скрипты и скрипты всех вложенных объектов теряются:
    source="@Embed(source='assets/Index.swf'#Index)"
    Игра с параметром mimeType не помогает.

На управлении внедренным контентом я бы хотел остановиться подробнее. Если у нас много однотипного материала для внедрения вышеописанным способом, то плодить SWF-файлы не удобно, плюс, внедряя каждый файл, мы не можем обобщать графику - она будет внедряться для каждого файла заново (не проверял, но догадываюсь).

Куда удобнее создать одну большую библиотеку и из нее внедрять символы. Но, к сожалению, их скрипты уже будут не доступны.
Но у нас есть в распоряжении метки фреймов и имена клипов. Совмещая возможности
MovieClip.currentLabels и MovieClip.addFrameScript можно получить контроль над внедренным клипом и заставлять его в нужный момент выполнять необходимые нам действия: останавливать клип на нужном фрейме, генерировать события и даже передавать данные в текстовые поля клипа.

Создаем компонент - наследник SWFLoader. После инстанцирования класса внедренного клипа (конец метода load(), можно так же добавить и в обработчик события загрузки), считываются все его метки и в их фреймы добавляются необходимые скрипты. Имя каждой метки имеет ключевую составляющую, которая и определяет тип действия добавляемого скрипта.
В нужный момент можно заставить клип остановиться, перейти на другую метку, генерировать событие (с идентификатором, так же зашитым в имя метки), просканировать клип и получить срез всех визуальных объектов, чтобы делать с ними всё что угодно. Главное - этот момент устанавливается прямо в таймлайне клипа, а не путем каких-либо расчетов количества фреймов или подобных методов.


Прекрасный момент - праздник еще не настал, а дидлайны уже позади! Отдыхать и набираться сил.

И конечно, наших прекрасных женщин поздравляю с праздником 8 марта!