GUI部品について[2] - 有限会社ITプランニング

haXeでオリジナルコンポーネント作り
WCAN mini Vol.10
2009.03.14
小笠原 啓@(有)ITプランニング
自己紹介
 有限会社ITプランニング所属のプログラマー。
 haXeとかObjective CamlとかActionScriptとかやってます。
 GUIとかマルチスレッドとか言語とかに興味持ってます。
Page 2
仕事:リッチインターネットアプリケーション
Page 3
話したいこと
 swfファイルを生成できるhaXeという言語の紹介。すばらしい言語だよ!
 コンポーネント(GUI部品)について。
 haXeで簡単にオリジナルコンポーネントを作れないものか?と考えてみた。
Page 4
まずは簡単にhaXe(へっくす)の紹介
 swf, javascript, neko, phpにコンパイルできるマルチプラットフォーム言語。
 静的型付け(型推論)、高階関数、列挙型、型パラメータ、構造的部分型。
 オープンソース。http://haxe.org/?lang=jp
Page 5
こんにちは世界(みかけはAS3によく似ています)
import flash.text.TextField;
class Test {
public static function main() {
var msg = new TextField();
msg.txt = “こんにちは” + “世界!”;
flash.Lib.current.addChild( msg );
}
}
Page 6
haXeのすごいところ[1]
 型付けされた高階関数と型推論。
高階関数
function reduce( f : T → T→T, init : T, ary : Array<T> ) : T {
var result = init;
型推論
for( elm in ary ) {
result = f ( result, elm );
}
return result;
}
Page 7
haXeのすごいところ[2]
 列挙型
enum Card {
Number ( n : Int );
トランプは、数字を持つカードか
ジョーカーのどちらかという表現。
Jocker;
}
 構造的部分型
typedef Point = { x : int; y : int };
class Point3D = { var x : int; var y : int; var z: int; }
function move( p : Point ) : Void { p.x++; p.y++; }
move( new Point3D() )
Page 8
型チェックOK!
haXeのすごいところ[3]
 クライアント・サーバーの両方が記述できて、連携が取れる。
 例えばサーバーサイドはneko, クライアントサイドはFlash。
 haxe.remoting.HttpConnectionなどを使ってデータの授受。同じ言語でやり方
が同じなので、連携が容易。
Page 9
GUI部品について[1]
1.
イベントの上がり方を変えたい。
無理。
2.
動きを変えたい。
用意されているものがあれば。
3.
~をしたい。
イベントとかプロパティとかメソッドとか多すぎ。
Page 10
GUI部品について[2]
 なぜそうなっているのか?
1. 下手にクラスの中身をプログラマーに公開すると破壊するので、隠蔽工作を
している。
2. Model-View-Controlというクラス間の相互依存関係をうまく回避する歴史的
な(?)テクニックを鵜呑みにして使っている。
Page 11
どうすれば柔軟なGUI部品が作れるのか?
GUI部品の動作を作るときには、自然言語では次のように考えることが多い。
1. ~というイベントが起きたときに、
2. ~という条件を調べて、
3. ~というフィードバックを表示して、
4. ~を実行する。
Page 12
インタラクションという名前でまとめてみた
class UXInteraction<S> {
インタラクションを発動させる(低レ
ベル)イベント
var name : String;
フィードバック
var events : Array<String>;
var acts : Array<S → Void>;
var judge : S → Bool;
イベントを挙げるかどうか?
var work : S → UXInteractionParameter → Void;
}
イベントが起きたときに実行する事
Page 13
インタラクションの使い方(作る)
class SomeInteraction extends Interaction<State> {
public function new( ?c : Controller<State> ) {
super(c); name = "SomeInteraction";
events.push( MouseEvent.CLICK );
judge = function ( state : State ) { return state.enable; };
work = function ( state : State, param : Null<InteractionParameter> ) {
state.enable = !state.enable;
};
acts.push( function ( state : State ) {
for( c in state.children ) { c.x ++ ; c.y ++;}
} );
}
Page 14
}
インタラクションの使い方(変更する)
1. クリックを無効にして、エンターキーにのみ反応するボタン。
button.getInteraction(“push”).clearEvents();
button.getInteraction(“push”).addEvent(“UXKeyboard.ENTER”);
2. リストボックスの出現の仕方を変更する。
button.getInteraction(“drop”).addAct( function( s ) {
s.dropbox.alpha = 0.;
Tweener.add(s.dropbox, { alpha = 1.; time = 1.; });
}):
Page 15
デモンストレーション
Page 16
UX-Frameworkとして公開中
Subversionリポジトリ:
http://ux-framework.googlecode.com/svn/trunk
Blog:
http://ocaml-nagoya.g.hatena.ne.jp/uxtk/
Page 17
Web Site: www.itpl.co.jp Email: [email protected]
Page 18