ウィジェットクラスライブラリーで自作コントロールとテーマを作る

ウィジェットクラスライブラリーシリーズの続き、今回は自作コントロールの作成と、テーマの作成を行いたいと思います。
前回紹介した日本語訳マニュアルを片手にご用意ください。

ウィジェットクラスライブラリー文書日本語訳
前回の文書解説とサンプル

一番下に今回作った自作コントロールを使ったサンプルウィジェットを置いておきました。

7ページ目、独自クラスを作る、のところから始めましょう。
ここは、JavaScriptでクラス継承を書いたことがあるかによってかなりわかりやすさが違ってくると思います。

まず名前空間に関しては、要するに、ないので、入れ子オブジェクトでエミュレートしましょう、ということです。
var Yahoo = { Samples: { MySample: { MyClass: function(theme){/* クラスの定義 */} } } };
と言う入れ子オブジェクトを作れば、Yahoo.Samples.MySample.MyClass で、クラスそのものにアクセスできるので、
その入れ子オブジェクトを作っていきましょう、ということです。

継承チェインの定義については、JavaScriptでは幾つかの方法があると思いますが、
ここは、こういう物だ、とYahoo!流に従っておきましょう。
MyBaseを継承してMyClassを宣言するときに、下記のようになります。


// 親クラスのメソッドのコピー
Yahoo.Samples.MySample.MyClass.prototype = new Yahoo.Samples.MySample.MyBase();
// コンストラクターの再設定
Yahoo.Samples.MySample.MyClass.prototype.constructor = Yahoo.Samples.MySample.MyClass;
// 親クラスのメソッドのバックアップコピー
Yahoo.Samples.MySample.MyClass.prototype.baseclassMyClass = Yahoo.Samples.MySample.MyBase.prototype;

親クラスのメソッドのバックアップは、継承側でクラスのオーバーライドを行ったとき、
super呼び出しをしたくなった場合に使うと良いでしょう。
prototype.baseclassクラス名 を使うのはYahoo!でのコーディング規約と考えれば良いでしょう。

独自コントロールの作成について、今回はTextBoxクラスを継承したTextFieldクラスを作ってみます。
TextFieldクラスは、入力欄が1行しかなく、改行を入力できないTextBoxクラスです。
ちょっと本来の継承の意味合いからするとよろしくなさそうなのですが、サンプルということでご勘弁ください。


lib.include("Yahoo.Controls.SizableControlBase");
lib.include("Yahoo.Controls.TextBox");

// TextBox
var textBox = new Yahoo.Controls.TextBox(frmCoolWindow.theme);
frmCoolWindow.addControl(textBox);
textBox.width = 200;
textBox.height = 25;

通常のテキストボックスでは、縦幅を制限しても、Enterキーを入力することができてしまいます。
これは、TextBoxが内部的にTextAreaをもっているためなので、本来はTextをもつ別クラスがあっても良いはずです。
ですが、たとえば下記のように、イベントハンドラーで改行コードの入力をキャンセルすることも可能です。
これは、クラスの継承をする代わりに、イベントハンドラーを設定した例になります。


// TextBox with custom event handlers
var textBox2 = new Yahoo.Controls.TextBox(frmCoolWindow.theme);
textBox2.width = 200;
textBox2.height = 25;
// cancel the enter key
textBox2.addEventHandler(function(sender, e)
{
var code = e.key.charCodeAt(0);
if (code == 10 || code == 13)
{
sender._txtTextBox.rejectKeyPress();
e.cancel = false;
}
}, 'KeyPress');
// adjust the multi line paste
// replace with a white space
textBox2.addEventHandler(function(sender, e)
{
var text = sender.text;
if (/[\n\r]/.test(text))
sender.text = text.replace(/[\n\r]+/g, ' ');
}, 'TextChanged');
frmCoolWindow.addControl(textBox2);

sender._txtTextBox が内部のTextAreaオブジェクトで、ここのオブジェクトをいじってしまっても
良いのかは若干あやしいですが、ひとまずこれで入力のキャンセルができます。
onTextChanged にも対応させることで、コピー&ペーストで複数行が貼り付けられた場合にも対応できています。

このようなコントロールを複数作りたくなった場合を考えると、
クラスを作ってしまえば、呼び出し側は下記のように簡潔になります。


// TextField
lib.include("NonnEtTwk.Wcl.Controls.TextField");

var textField = new NonnEtTwk.Wcl.Controls.TextField(frmCoolWindow.theme);
frmCoolWindow.addControl(textField);
textField.width = 200;
textField.height = 25;

今回は独自の名前空間 NonnEtTwk.Wcl.Controls を用意しました。
ファイルの置き場は、Library/NonnEtTwk/Wcl/Controls/TextField.v1.01.jsとなります。
v1.01の部分はライブラリーのバージョンを表しているので、Yahooのコントロール側のバージョンに揃えてください。

中身は、名前空間部分


if(NonnEtTwk==undefined) { var NonnEtTwk = {}; }
if(NonnEtTwk.Wcl==undefined) { NonnEtTwk.Wcl = {}; }
if(NonnEtTwk.Wcl.Controls==undefined) { NonnEtTwk.Wcl.Controls = {}; }

コンストラクター (他のコントロールの記述に合わせてあります)


NonnEtTwk.Wcl.Controls.TextField = function(theme) {

//log("TextField.ctor()");
if(arguments.length>0) {
this.initialize(theme);
}
};

本物の初期化メソッド


NonnEtTwk.Wcl.Controls.TextField.prototype.initialize = function(theme) {

// log("TextField.initialize()");

// Call baseclass constructor
this.baseclassTextField.initialize.call(this, theme);
};

そして2つのイベントハンドラー


NonnEtTwk.Wcl.Controls.TextField.prototype._onKeyPress = function(sender, e) {

// log("TextField._onKeyPress");

var code = e.key.charCodeAt(0);
if (code == 10 || code == 13)
{
this._txtTextBox.rejectKeyPress();
e.cancel = false;
return;
}

this.baseclassTextField._onKeyPress.call(this, sender, e);
};

NonnEtTwk.Wcl.Controls.TextField.prototype._onTextChanged = function(sender, e) {

// log("TextField._onTextChanged");

this.baseclassTextField._onTextChanged.call(this, sender, e);

var text = this.text;
if (/[\n\r]/.test(text))
this.text = text.replace(/[\n\r]+/g, ' ');
};

となります。this.baseclassTextFieldを使っての
親クラスのメソッドの呼び出しも確認できると思います。

以上のクラスを使ったサンプルをウィジェットとして作りました。
デバッグはonにしてあります。

ウィジェットクラスライブラリー自作クラス

実行するとダイアログに三つの入力欄ができます。
それぞれ、TextBox、上記のイベントをつけたTextBox、TextFieldに相当します。お試しくださいませ。

次回は、自作テーマ作成に行きたいと思います。

Trackback URL for this post:

http://nonn-et-twk.net/twk/trackback/120
0