Приложение под цвет кофточки
Flex 4 предоставляет нам возможность легко изменять цветовую гамму всего приложения. Flash Player предоставляет доступ к веб-камере. Так почему-бы не попробовать раскрасить Flex-приложение на основе картинки с камеры? ![]()
Об использовании метафор
Очень понравилось в книге Объектно-ориентированное конструирование программных систем:
Все используют метафоры - аналогии - для обсуждения и обучения техническим проблемам.
…
Хорошо или плохо применять метафоры? Это может быть очень хорошо или очень плохо - все зависит от целей, для которых они используются.
…
Если мы начнем воспринимать метафоры в их повседневном смысле и начнем на этом основании делать выводы, то мы можем столкнуться с серьезными проблемами. Псевдосиллогизм ("Доказательство по аналогии") в форме:
A походит на B
B имеет свойство p
------------------
Ergo: A имеет свойство p
обычно порочен.
Встреча Flash-разработчиков 6 февраля 2010 - BURAFPUG
Долгожданная очередная встреча в Москве состоялась 6 февраля 2010 в офисе Adobe.

Началась она с того, что Рост сказал, что подходит к зданию и где-то пропадал еще 40 минут
На следующем фото Вы видите наших дорогих Артемия Малкова и Алексея Гончаренко, играющих в змейку отчаивающихся до него дозвониться.

Flex-модули в AIR
Проблема
Для нас это значит, что:
- Просто так загрузить модули в debug-режиме из папки вне bin-debug Вашего проекта нельзя. Также нельзя загружать модули по абсолютным путям (причем даже из bin-debug).
- Просто так загрузить модули в AIR-приложение с какого-либо сервера нельзя.
VerifyError: Error #1014: Class mx.modules::Module could not be found. at flash.display::MovieClip/nextFrame() at mx.core::FlexModuleFactory/deferredNextFrame()
Решение
Существует обход этого запрета. Достаточно предварительно загрузить .swf-файл через URLLoader, а затем загружать модуль не по ссылке, а как ByteArray:
- moduleInfo.load(null, null, byteArray);
P.S
Аналогичная проблема существует для стилей, там это решается через monkey-patching StyleManagerImpl.
Как обойти список запрещенных слов в ContextMenuItem
Только т-с-с. Известный список запрещенных слов можно обхитрить, добавив в конец строки символ с кодом 160 ![]()
Интервью при приеме на работу
Очень интересный текст на тему проведения интервью. Знать потенциальную стратегию “противника” - половина дела ![]()
Joel on Software
Увеличение размера проекта при переходе на Flex SDK 4
Цифры
Рассмотрим проект на Flex 3, загружающий фреймворк как RSL:
- name.swf: 65Kb - вес “пустого” приложения без какого-либо полезного кода
- framework.swz: 565Kb
При переходе на Flex 4 с использованием MX и Spark компонент:
- name.swf: базовый размер уменьшился на 5Kb
- framework.swz: вырос на 50Kb
- spark.swz: 272Kb
- textLayout.swz: 150Kb
- каждый модуль: базовый размер вырос на 20Kb
Итого
В общем случае получаем увеличение размера проекта на 470Kb.
Другой подход к стилизации Flex-приложения
Проблема
При использовании нескольких внешних файлов стилей все они являются copy-paste одного шаблона с разными цветами/картинками. Из этого следует, что:
- Каждый из SWF стилей может занимать от 30 Кб до 300 и более Кб, в то же время очевидно что их код во многом совпадает. Хотелось бы не грузить одно и тоже.
- Из-за отсутствия настоящей иерархии в стилях одни и те же цвета приходится указывать в множестве мест
- Создание нового стиля - нудная работа по копи-пасту и замене цветов и картинок по всему (возможно - огромному) CSS-файлу
- Нельзя дать сторонним разработчикам возможность делать свои стили - ведь классы и селекторы переименовываются, добавляются новые. В то время по сути цвета и картинки остаются те же.
- Нельзя дать пользователю возможность настроить приложение под свои цвета.
Решение
Решение работает по той же схеме, что и недавний пост про изменение размера текста в приложении.
Вместо указаний явных значений для стилей вроде “backgroundColor", “color", “borderThickness” - указываются идентификаторы значений ("color1″) для стилей “backgroundColorId", “colorId", “borderThicknessId” а реальные значения в них проставляются в процессе выполнения:
- Application
- {
- colorId: "color4";
- fontSize: 12;
- backgroundColorId: "color0";
- }
Стиль можно задать следующим образом:
- private var style1:Object =
- {
- color0: 0x222222,
- color1: 0x333333,
- color2: 0x666666,
- color3: 0xAAAAAA,
- color4: 0xDDDDDD
- };
Код применения нового стиля:
- /**
- * Applies style to the application.
- *
- * @param object Keys are Strings like "color1", values are real style
- * values ex. "0xFFCC00".
- */
- private function applyStyle(object:Object):void
- {
- var selectors:Array = StyleManager.selectors;
- var bitmapClassCacheIndex:int = 0;
- var n:int = selectors.length;
- for (var i:int = 0; i < n; i++)
- {
- var selector:String = selectors[i];
- var declaration:CSSStyleDeclaration =
- StyleManager.getStyleDeclaration(selector);
- for each (name in idAttributes)
- {
- var idValue:String = declaration.getStyle(name + "Id") as String;
- if (!idValue)
- continue;
- if (object[idValue] is BitmapData)
- {
- var bitmapClass:Class = RuntimeBitmapAsset.bitmapDatas[idValue];
- if (!bitmapClass)
- {
- bitmapClassCacheIndex =
- bitmapClassCacheIndex % bitmapClassCache.length;
- bitmapClass = bitmapClassCache[bitmapClassCacheIndex++];
- RuntimeBitmapAsset.bitmapDatas[getQualifiedClassName(
- new bitmapClass())] = object[idValue];
- }
- declaration.setStyle(name, bitmapClass);
- }
- else if (object.hasOwnProperty(idValue))
- {
- declaration.setStyle(name, object[idValue]);
- }
- else
- {
- declaration.clearStyle(name);
- }
- }
- StyleManager.setStyleDeclaration(selector, declaration, i == n - 1);
- }
- }
Runtime иконки для Flex-компонент
Проблема
Flex SDK позволяет в качестве значение стиля “icon” для mx.controls.Button и других icon-стилей других компонент указывать только Class, экземпляры которого будут удовлетворять IFlexDisplayObject. Обычно это делается так:
- [Embed("mouse.png")]
- private var icon1:Class;
- <mx:Button icon="{icon1}"/>
Проблема в том, что mouse.png может определяться в процессе работы приложения.
Возможные пути решения
По мере поступления картинок компилировать из них SWF и подгружать.
Данный метод не всегда доступен и не удобен.
Сделать monkey-patch соответсвующих компонент SDK.
При смене версии Flex SDK возможно придется изменять и патчи. Также monkey patching приносит проблемы при работе с RSL. (eng)
Сгенерировать SWF с картинкой на лету.
Для этого придется изучить SWF Specification и AVM2 Bytecode.
Я разбирал уже скомпилированную SWF с одной картинкой, дошел до байткода. В случае PNG с прозрачностью выяснилось, что маска прозрачности, похоже, хранится отдельно, а сама картинка хранится в байткоде, так что не ждите легкого решения. По дороге выяснилось, что минимальный размер SWF - где-то 30 байтов.
Использовать несколько заранее вкомпилированных классов и ассоциировать с ними BitmapData по мере необходимости.
Этот способ будет рассмотрен далее.
Кеш классов-наследников BitmapAsset
Класс-картинка должен просто вызвать родительский конструктор BitmapAsset, передав ему нужное значение BitmapData. Реазилуем это следующим образом:
- package bitmaps
- {
- import flash.display.BitmapData;
- import flash.display.PixelSnapping;
- import flash.utils.getQualifiedClassName;
- import mx.core.BitmapAsset;
- public class RuntimeBitmapAsset extends BitmapAsset
- {
- /**
- * Maps class names to BitmapData instances.
- */
- public static const bitmapDatas:Object = {};
- public function RuntimeBitmapAsset()
- {
- var name:String = getQualifiedClassName(this);
- var bitmapData:BitmapData = bitmapDatas[name];
- if (!bitmapData)
- trace("Warning: BitmapData for \"" + name + "\" not found");
- super(bitmapData, PixelSnapping.AUTO, true);
- }
- }
- }
Далее создаем нужное количество классов-приспособленцев B0, B1, B2 …:
- package bitmaps
- {
- public class B0 extends RuntimeBitmapAsset
- {
- }
- }
Использование
- import flash.utils.getQualifiedClassName;
- import bitmaps.*;
- import mx.controls.Button;
- /**
- * Array of Class-es.
- */
- private var bitmapClasses:Array = [ B0, B1, B2 ];
- /**
- * Index of next available element in bitmapClasses
- */
- private var index:int = 0;
- private function addSample():void
- {
- if (container.numChildren == bitmapClasses.length)
- container.removeChildAt(0);
- var button:Button = new Button();
- button.label = "Button with icon using cache class B" + index;
- var theClass:Class = getNextBitmapClass(getRandomBitmapData());
- button.setStyle("icon", theClass);
- container.addChild(button);
- }
- private function getNextBitmapClass(bitmapData:BitmapData):Class
- {
- var bitmapClass:Class = bitmapClasses[index];
- index = (index + 1) % bitmapClasses.length;
- RuntimeBitmapAsset.bitmapDatas[getQualifiedClassName(new bitmapClass())] = bitmapData;
- return bitmapClass;
- }
- private function getRandomBitmapData():BitmapData
- {
- var bitmapData:BitmapData = new BitmapData(16, 16, true, 0);
- var seed:Number = Math.floor(Math.random() * 10);
- var channels:uint = BitmapDataChannel.RED | BitmapDataChannel.BLUE;
- bitmapData.perlinNoise(100 * Math.random(), 100 * Math.random(), 10 * Math.random(),
- seed, false, true, channels, false, null);
- return bitmapData;
- }
:: Следующие >>








