ラベル Adobe AIR の投稿を表示しています。 すべての投稿を表示
ラベル Adobe AIR の投稿を表示しています。 すべての投稿を表示

2009-11-06

Adobe AIR 2のベータ公開お知らせサービス

ここで、Adobeのアカウントを登録すると、Adobe AIR 2のベータ版公開時にお知らせしてくれるんだって!



��>Adobe AIR 2 Beta Notification - Adobe Labs



もちろん、ベータの段階では英語版しかないけども。



Adobe AIR 2では、パフォーマンスの改善はもちろんのこと、外部記憶デバイスの認識、マイクからの音声取り出し、マウスジェスチャー・マルチタッチ対応、HTML5/CSS3のWebKitなど、大幅に拡張されるみたいです。



Blogではマルチタッチの動画が上がってた。

まだ、タッチスクリーン自体は普及してないけど、iPhoneの流れからすれば、段々一般的な入力デバイスになっていくのかな。



��>Cynergy Systems Demos Adobe AIR 2 Multi-touch Support - Adobe AIR Team Blog





これからのAIRの発展に期待。

2009-08-14

【AIR】NativeWindowクラスによるウインドウ操作

AIRで追加されたNativeWindowクラス.

ウインドウ操作を扱うクラスで,簡単にウインドウを生成・制御可能.

Flash独特のグラフィックス環境を用いて,オリジナルのスキンでウインドウを作ることができる.

そのサンプルがこれ.

あまり一般的な書き方してないけど.

 
package {
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.display.NativeWindow;
import flash.display.NativeWindowType;
import flash.display.NativeWindowInitOptions;
import flash.display.NativeWindowSystemChrome;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.geom.Rectangle;
import flash.display.DisplayObject;

// Tweener(ウインドウのエフェクト用)
import caurina.transitions.Tweener;
import caurina.transitions.properties.FilterShortcuts;


public class NativeWindowEx extends NativeWindow {
protected var base:Sprite;
// ウインドウのオリジナルスキン(CS4で作成後Sprite継承でASに書き込み指定)
private var skin:DialogSkin;

public function NativeWindowEx(initX:int, initY:int, initTitle:String, initDO:DisplayObject) {
// NativeWindowのオプション
var nwOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
// ウインドウタイプ
nwOptions.type = NativeWindowType.LIGHTWEIGHT;
// システムクロームの設定
nwOptions.systemChrome = NativeWindowSystemChrome.NONE;
// ウインドウにalpha値を適用するかどうか
nwOptions.transparent = true;
// 最小化できるかどうか
nwOptions.minimizable = true;
// 最大化できるかどうか
nwOptions.maximizable = false;
// ウインドウサイズを変更できるかどうか
nwOptions.resizable= false;
super(nwOptions);

base = new Sprite();
base.alpha = 0.0;
// NativeWindowの持つstageにaddChild
this.stage.addChild(base);

skin = new DialogSkin();
skin.window.addEventListener(MouseEvent.MOUSE_DOWN, skinWindowDragHandler);
skin.close.addEventListener(MouseEvent.MOUSE_DOWN, skinCloseButtonHandler);
skin.close.addEventListener(MouseEvent.MOUSE_OVER, skinCloseMouseOverHandler);
skin.close.addEventListener(MouseEvent.MOUSE_OUT, skinCloseMouseOutHandler);
// 貼り付ける内容に合わせてスケール変換(skinはscale9Gridを設定済み)
skin.close.scaleX = (initDO.width) / 490;
skin.close.scaleY = (initDO.height) / 300;
skin.window.scaleX = (initDO.width) / 490;
skin.window.scaleY = (initDO.height) / 300;
skin.x = 10;
skin.y = 10;
base.addChild(skin);

var rect:Rectangle = skin.scale9Grid;
initDO.x = rect.left + 10;
initDO.y = rect.top + 10;
base.addChild(initDO);

super.activate();

this.x = initX;
this.y = initY;
this.width = skin.width + 20;
this.height = skin.height + 20;
this.title = initTitle;
this.stage.scaleMode = StageScaleMode.NO_SCALE;
this.stage.align = StageAlign.TOP_LEFT;
this.addEventListener(Event.CLOSE, windowCloseHandler);
// フェードインでウインドウを表示
Tweener.addTween(base, {alpha:1.0, time:0.5, transition:"linear"});
}

public function deleteReference():void {
skin.window.removeEventListener(MouseEvent.MOUSE_DOWN, skinWindowDragHandler);
skin.close.removeEventListener(MouseEvent.MOUSE_DOWN, skinCloseButtonHandler);
skin.close.removeEventListener(MouseEvent.MOUSE_OVER, skinCloseMouseOverHandler);
skin.close.removeEventListener(MouseEvent.MOUSE_OUT, skinCloseMouseOutHandler);
}

// Event Handler /////////////////////////////////////////////
private function skinCloseMouseOverHandler(event:MouseEvent):void {
// マウスオーバーでGlowエフェクト
Tweener.addTween(event.currentTarget, {time:0.5, transition:"linear",
_Glow_alpha:0.7, _Glow_blurX:15, _Glow_blurY:15,
_Glow_color:0x00CCCC,
_Glow_quality:1, _Glow_strength:1});
}

private function skinCloseMouseOutHandler(event:MouseEvent):void {
// マウスアウトでGlowエフェクト解除
Tweener.addTween(event.currentTarget, {time:0.5, transition:"linear",
_Glow_alpha:0});
}

protected function windowCloseHandler(event:Event):void {
this.removeEventListener(Event.CLOSE, windowCloseHandler);
}

private function windowCloseTweenComp():void {
super.close();
deleteReference();
}

protected function skinWindowDragHandler(event:MouseEvent):void {
this.startMove();
}

protected function skinCloseButtonHandler(event:MouseEvent):void {
// フェードアウトでウインドウを閉じる
Tweener.addTween(base, {alpha:0.0, time:0.5, transition:"linear",
onComplete:windowCloseTweenComp});
}
}
}

NativeWindowInitOptionsで事前に作成するウインドウの設定.

オリジナルスキンを使うなら,

nwOptions.systemChrome = NativeWindowSystemChrome.NONE;

としておく.



新しく作ったウインドウにどうやってオブジェクトを表示するかというと,実は今までのやり方と全く変わらない.

this.stage.addChild(base);

というように,実は各NativeWindowがstageを所持している.

だから,今まで同様に,NativeWindow内のstageにaddChildすればいい.

つまり,表示オブジェクト的にFlashとAIRでは,



Flash:stageをトップとした階層構造

AIR :1つまたは複数のNativeWindow内のstageをトップとした階層構造



という違いがある.







各NativeWindowのメソッドについて.



activateでウインドウにフォーカスする.



このメソッドを呼び出すか,visibleをtrueにしないとウインドウが表示されないので注意.

closeでウインドウを閉じる.



startMoveでウインドウをドラッグ.

これ呼び出すだけで自動でドラッグされるとかwゆとり仕様乙

2009-07-25

【AIR】XMLを非同期に読み書きする【FileStream】

都合上,XMLを自由に読み書きする必要が出てきた.



そこで,FileStreamクラス(AIRで追加されたファイルの読み書き用クラス)を使い,

XMLのメソッド1つで,非同期に読み書きをするXMLManagerクラスを作ってみた.



package {
import flash.events.EventDispatcher;
import flash.events.OutputProgressEvent;
import flash.events.Event;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;

/** XML用クラス
* @auther kusamochi
* @extend EventDispatcher
*/
public class XMLManager extends EventDispatcher {
public static const READ_COMPLETE:String = "read_complete";
public static const READ_CLOSE:String = "read_close";

public static const WRITE_PROGLESS:String = "write_progress";
public static const WRITE_CLOSE:String = "write_close";

private var _xml:XML;  // [read]xmlファイルの実体
private var fileStream:FileStream;
private var _mode:String;

//コンストラクタ
public function XMLManager() {
_mode = "NormalMode";
}

// 明示的な参照解除メソッド
public function deleteReference():void {
if(fileStream) {
if(_mode == "ReadMode") {
fileStream.removeEventListener(Event.COMPLETE, readStreamCompleteHandler);
fileStream.removeEventListener(Event.CLOSE, readStreamCloseHandler);
}
else if(_mode == "WriteMode") {
fileStream.removeEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeStreamOutputProgressHandler);
fileStream.removeEventListener(Event.CLOSE, writeStreamCloseHandler);
}
}
}

// ファイル読み込み
public function readXML(file:File):void {
trace("XMLManager::readXML");
trace("Reading : " + file.nativePath);

_mode = "ReadMode";
fileStream = new FileStream();
fileStream.addEventListener(Event.COMPLETE, readStreamCompleteHandler);
fileStream.addEventListener(Event.CLOSE, readStreamCloseHandler);
fileStream.openAsync(file, FileMode.READ);
}

// ファイル出力
public function writeXML(file:File):void {
trace("XMLManager::writeXML");
trace("Writing : " + file.nativePath);

_mode = "WriteMode";
fileStream = new FileStream();
fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeStreamOutputProgressHandler);
fileStream.addEventListener(Event.CLOSE, writeStreamCloseHandler);
fileStream.openAsync(file, FileMode.WRITE);
fileStream.writeMultiByte(_xml.toXMLString(), File.systemCharset);
}

public function printXML():void {
trace(_xml.toXMLString());
}

// EventHandler ///////////////////////////////////////////////////////////
// Read  ----------------------------------------
// Readストリームがクローズ
private function readStreamCloseHandler(event:Event):void {
trace("XMLManager::readStreamCloseHandler");
fileStream.removeEventListener(Event.COMPLETE, readStreamCompleteHandler);
fileStream.removeEventListener(Event.CLOSE, readStreamCloseHandler);
_mode = "NormalMode";

// カスタムイベントを配信する
super.dispatchEvent(new Event(READ_CLOSE));
}

// 読み込み完了
private function readStreamCompleteHandler(event:Event):void {
trace("XMLManager::readStreamCompleteHandler");
var tmpStr:String = fileStream.readMultiByte(fileStream.bytesAvailable, File.systemCharset);
fileStream.close();
_xml = new XML(tmpStr);

// カスタムイベントを配信する
dispatchEvent(new Event(READ_COMPLETE));
}

// write --------------------------------------
// Writeストリームがクローズ
private function writeStreamCloseHandler(event:Event):void {
trace("XMLManager::writeStreamCloseHandler");
fileStream.removeEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeStreamOutputProgressHandler);
fileStream.removeEventListener(Event.CLOSE, writeStreamCloseHandler);
_mode = "NormalMode";

// カスタムイベントを配信する
super.dispatchEvent(new Event(WRITE_CLOSE));
}

// Write進行中
private function writeStreamOutputProgressHandler(event:OutputProgressEvent):void {
trace("XMLManager::writeStreamOutputProgressHandler");
if(event.bytesPending == 0){
fileStream.close();
}

// カスタムイベントを配信する
super.dispatchEvent(new OutputProgressEvent(WRITE_PROGLESS));
}

// getter ////////////////////////////////////////////////////
// XMLオブジェクトを返す(他のクラスからのアクセスに対応)
public function get xml():XML {
return _xml;
}

// mode
public function get mode():String {
return _mode;
}

// setter //////////////////////////////////////////////
public function set xml(setXML:XML) {
_xml = setXML;
}

}
}

FileStreamクラスのファイルオープンには,openメソッド,openAsyncメソッドの2つがある.

openメソッドを使うと,それ以降のFileStreamの処理は,その行の処理が終わるまで次の行を実行しない

でも,それだと,ロード対象のサイズが大きくなった場合などに遅延が起きてしまう.



それを避けたいのなら,openAsyncメソッドでファイルオープンする.

openAsyncにすると,各処理ごとにイベントを発行する.

つまり,FileStreamのオブジェクトにaddEventListenerしとけば,読み込み終わりとか判定できるわけです.



そこで,上記のXMLManagerでは,各イベントを利用してMXLの読み書きを行い,さらにカスタムイベントを配信する.

EventDispatcherを継承したのはこのため.





これ,作るときに気づいたんだが,

READモードだとcompleteイベント発生するのに,WRITEモードではcompleteイベント発生しないんだね.

最初気づかずにWRITEモードでもcompleteでファイルクローズしてたから,

イベント自体が発生してないからクローズされていないってことで,

上書き時にエラー出て散々ハマりましたw



しょうがないんで,OutputProgressイベント(出力中に定期的に発生するイベント)を使って,

bytesPending(残りの書き込みバイト数)がゼロになったときにクローズするようにしてみた.



2009-07-23

【AIR】applicationDirectoryのセキュリティエラー【Fileクラス】

Fileクラスは,AIRで追加された,一括したファイル・ディレクトリ管理ができる万能クラス.

便利なのはいいんだけど,セキュリティーエラーにハマっちゃって・・・.

ハマった割にはたいしたこと無かったけど,知らなかったら解決しない問題なのでメモしておく.




// 保存先
var oldPlayData:File = (File.applicationDirectory).resolvePath("pd.ini");
// 一時保存先
var newPlayData:File = File.createTempFile();

// どこかでoldPlayDataの内容を読み込み

// どこかでoldPlayDataから更新された内容をnewPlayDataに一時的に保存

// 以下,ウインドウを閉じるときに
// newPlayDataが存在するか確認
if(newPlayData.exists) {
try {
// newPlayDataの内容をoldPlayDataにコピー
newPlayData.copyTo(oldPlayData, true);
}
catch(error:Error) {
trace(error.message);
}

try {
// newPlayDataを削除
newPlayData.deleteFile();
}
catch(error:Error) {
trace(error.message);
}
}

以下,プログラムの構成.



静的プロパティFile.applicationDirectoryはアプリケーションのインストール先を指すFileオブジェクト.

さらに,resolvePathメソッドでpd.iniというファイルパスを作成し,ファイルの保存先(oldPlayData)とする.



さらに,File.createTempFileメソッドで一時保存先(newPlayData)を確保.



oldPlayDataから更新内容があった場合,一時保存先に更新内容を記録しておく.

このへんのプログラムは本題でないので省略.



ウインドウを閉じる時,

一時保存先からコピーしてpd.iniに書き込んだのち,一時保存先のファイルを削除する.





これだけのプログラムなのに,何故か最初のtryで「SecurityError: fileWriteResource」





どーなってんのってググってみたら,

どうやら,applicationDirectoryにおいて,ファイルを作成・書き込みすることはセキュリティ上認められていないらしい.



( ´゚д゚`)エー



その抜け道として,コピー前に,


oldPlayData = new File(oldPlayData.nativePath);


というように,一度nativePath(絶対パスのString)からFileクラスを再宣言すると,

セキュリティエラーから抜けられるとか.



でもそのかわり,

・AIRアプリケーションアンインストール時に自分で作成したファイルは削除されない

・作成したファイルが残っている状態で再インストールしようとするとエラーが発生

引用: applicationDirectory配下のファイルにアクセスする方法 - Fores Labs



あーだめだこれw



素直に,


// アプリケーションのプライベート記憶領域を指定
var oldPlayDataFile:File = (File. applicationStorageDirectory).resolvePath("pd.ini");

とするのが妥当かな.

これだと,applicationStorageDirectoryは,実際のディレクトリ位置がOSによって,

・Windowsの場合
C:\Documents and Settings\[ユーザ名]\Application Data\[AIRアプリID]
\Local Store

・Macの場合
HD/Users/[ユーザー名]/Library/Preferences/[AIRアプリID]/Local Store/

となるので,上記のresolvePathでpd.iniを指定した場合は,


・Windowsの場合
C:\Documents and Settings\[ユーザ名]\Application Data\[AIRアプリID]
\Local Store\pd.ini

・Macの場合
HD/Users/[ユーザー名]/Library/Preferences/[AIRアプリID]/Local Store/pd.ini

となる.

どうやら,このディレクトリはアンインストールと同時に消去されるらしい.





結論:

applicationDirectoryはファイルの書き込みには使用しない

��使うなら読み込み時.事前にパッケージしたswfとか画像データとかを読み込むのに使えばいい)



2008-07-28

【AIR】自己組織化マップ サンプルプログラム

今日,授業で自己組織化マップ(SOM)の発表会ですた.
内容は,「自分の手を入力として,それに格子状のニューロンが収束する様を見て楽しみましょう」というもの.

見て楽しむということで当然GUIですよ.
でも,JavaでSwingとか,VCでMFCとか正直やってらんないよね.
なので,AIRで作っちゃいました!

ダウンロードは↓
SOM Sample ver.2.0
※このプログラムはAIRアプリケーションです.実行にはAdobe AIRが必要です.

SOM Sample ver.2.0

くさもちは,GUIに困ると(AIRで)ついやっちゃうんだ!

まあ,AIR使ってるのはローカルから画像ファイルを読み込めるところだけど.
なので,そのうちFlash版も作っておこうかと思う.

使い方
とりあえず,Drawing Spaceにマウスでお絵かきするか,「Open」ボタンで画像を読み込む.
画像の場合,基本は2値画像または2値画像の白の部分を透過にしたもの.
普通の画像でもできなくはないけどね.
黒以外のピクセルがニューロンへの入力となります.
ニューロン数,学習率,繰り返し回数の上限を設定後に「Set」ボタンでセット.「Start」ボタンで実行します.
実行中,「Skep」の値を上げるとその値だけ描画を省いて表示するので,更新の速度が早くなります.

2008-07-20

(゚∀゚)キタコレ!! AIRアプリケーション

近年,従来のWeb環境を改善するアプリケーションとして,Rich Internet Application(RIA)が注目されている.

RIAは,JavaScript,XML,Flashなどを用いることで,Webブラウザ上でユーザにとって自由度の高いユーザーインターフェースの提供を可能とする( ´_ゝ`)フーン.

このような背景のもと,アドビシステムズはRIAをデスクトップアプリケーションとして開発,実行するためのランタイムライブラリとしてAdobe Integrated Runtime(AIR)をリリースした(2008年2月ヽ(゚Д゚)ノ新しい!!).

AIRを用いることで,自由度の高いユーザーインターフェースを持ったデスクトップアプリケーションの作成が可能となるΣ( ゚Д゚) スッ、スゲー!!.

本発表では,AIRの概要とFlash開発側の視点からAIRアプリケーションの構築について簡単に説明する.

さらに,実際にAIRが用いられた例をいくつか紹介する.





・・・という内容で自主ゼミしてきました.

ゼミ用にサンプルプログラムを3つほど作ってみました.

今回は,その中のひとつのアプリをうpしますた.



MyTurn.air





なお,これはAIRアプリなので,Adobe AIRがインスコされてないと動きません.

Adobe AIRがインスコされていると,

ファイルを実行すると,インストーラが立ち上がります.

てきとーなところインスコすればおk.

なお,アンインスコは各自OSの機能からやってください.







・・・



これはひどいwww