10.9 メッセージ履歴のカスタマイズ 〜基本編〜(その6)

今回は dispInit メソッドの残りの部分を全部見てくね。
前回で STEP 3 が終わったから、STEP 4 〜 STEP 6 になるんだっけ?
そ。じゃ早速スクリプトを見てくね。

HistoryLayer クラスの dispInit メソッド(HistoryLayer.tjs より抜粋)>

function dispInit()
{
    // 全部再描画と初期設定

    makeButtons(); // STEP 1:ボタンを作成

    (中略)

    // STEP 2:メッセージをすべて消去
    clearBack();

    if(everypage)
    {
        // STEP 3-1:ページ単位の初期履歴メッセージ表示処理(スクリプトは省略)
    }
    else
    {
        // STEP 3-2:行単位の初期履歴メッセージ表示処理(スクリプトは省略)
    }

    // STEP 4:ボタンの表示状態を更新
    updateButtonState();

    // STEP 5:メッセージ履歴レイヤを可視状態に設定
    visible = true;

    // メッセージ履歴レイヤをモーダル状態に設定
    // メッセージ履歴レイヤをモーダル状態にすると、メッセージ履歴レイヤとその子レイヤだけが
    // マウスやキーボードからの入力を受け取ることができるようになります
    setMode();

    // メッセージ履歴レイヤにフォーカスを設定
    // フォーカスが設定されるとキーボードからの入力を受け取れるようになります
    focus();

    // 最後にホイールを操作した時刻をリセット
    // この値はマウスホイール操作で履歴メッセージをスクロールする時に使われます
    lastWheelTick = 0;

    // メッセージ履歴レイヤ上でのマウスカーソルをデフォルトのマウスカーソルに設定
    // デフォルトのマウスカーソルとは Config.tjs の cursorDefault の値
    // もしくは cursor タグの default 属性に指定されているマウスカーソルです
    cursor = window.cursorDefault;
}
※一部コメントを追加しています。

今回は STEP 4 からだから、ここからだね。
updateButtonState っていうメソッドを呼び出してるとこだね。
このメソッドは「前ページ」ボタンと「次ページ」ボタンの表示を更新するためのメソッドなんだけど、 カスタマイズしたメッセージ履歴画面ではどっちのボタンも使わないから、 updateButtonState メソッドでやることは何もないんだ。
じゃ updateButtonState メソッドは呼び出さなくってもいいってことだよね?
まぁそーなんだけど、HistoryLayer クラスのスクリプトを勝手に書き換えるわけにもいかないからね。
そっか…HistoryLayer クラスって元から system フォルダにあるスクリプトに書いてあるクラスだもんね。
じゃあ、どーやって updateButtonState メソッドを呼び出さないようにするの?
updateButtonState メソッドを呼び出さないようにするんじゃなくって、呼び出されても何にもしないようにするの。
え、それってどーゆーコト?
メソッドのオーバーライドは知ってるよね。
※メソッドのオーバーライドについては §2.7 参照。
えっと、スーパークラスにあるのと同じ名前のメソッドをサブクラスにも作ること、だよね?
ん、そう。今はスーパークラスが HistoryLayer クラスで、 サブクラスが ExtendedHistoryLayer クラスだよね。
で、ExtendedHistoryLayer クラスの方の updateButtonState メソッドをこんなふうにオーバーライドするんだ。

ExtendedHistoryLayer クラスの updateButtonState メソッド>

function updateButtonState()
{
    // このメソッドの中では何もする必要ありません
}

コメントが書いてあるだけ…?
だから呼び出されても何にもしないわけね。
これで updateButtonState メソッドが呼び出されても何もしなくなるの?
うん。
えっと、でも確かサブクラスのメソッドを呼び出したら、その中でスーパークラスのメソッドも呼び出されるんじゃなかったっけ?
今までは大抵サブクラスのメソッドの中でスーパークラスのメソッドを呼び出してたからそんな気がするかもしれないけど、 “super.updateButtonState();”みたいにスーパークラスのメソッドを呼び出すスクリプトを実行しない限りはスーパークラスのスクリプトは呼び出されないよ。
あ、そーなんだ。
ってワケだから、これで STEP 4 は終了。
…って言っても何にもやってないよね。
まぁね。でもこれでいいの。
じゃ次は STEP 5メッセージ履歴レイヤの visible プロパティを設定するとこだね。
visible = true;” だから、メッセージ履歴レイヤが見えるようにしてるんだよね。
そういうこと。
はい、じゃこれで STEP 5 は終わり。
えっ、もう終わり?
メッセージ履歴レイヤを表示すればメッセージ履歴画面全体が表示されるから、これだけで OK だよ。
この後にもいくつか処理があるんだけど、今回のカスタマイズとは直接関係ないから、詳細は省略させてもらうね。
りょーかい。
HistoryLayer クラスの dispInit メソッドでやるのは STEP 5 までで、 STEP 6 は ExtendedHistoryLayer クラスの dispInit メソッドで実行するから、 次は ExtendedHistoryLayer クラスの dispInit メソッドの方を見てくね。

ExtendedHistoryLayer クラスの dispInit メソッド(再掲)>

function dispInit()
{
    // STEP 1〜5:スーパークラス(HistoryLayer クラス)の dispInit メソッドを呼び出します
    // (メッセージ履歴テキストの書き込みなどはここで実行されます)
    super.dispInit();

    // STEP 6:スクロールバーの設定をします
    if(canScroll)
    {
        // スクロールバーが必要な場合は canScroll が true になります
        scrollBar.maxVal = dispStart; // 最大値を設定します
        // スライダー(ドラッグして動かせる部分)の長さを設定します
        scrollBar.ratio = everypage ? (1 / dataPages) : (dispLines / dataLines);
        scrollBar.value = dispStart; // 現在値を設定します
    }
    // スクロールバーが必要(canScroll が true)なら表示状態
    // 不必要(canScroll が false)なら非表示状態にします
    scrollBar.visible = canScroll;
}

STEP 1〜5 までをスーパークラスの dispInit メソッドでやってるから…
STEP 6 は if ブロックのとこからだよね。
ん、そう。
どんな時に if ブロックの中身が実行されるかはわかるよね?
canScrolltrue の時だから、履歴メッセージがスクロールできる時だよね。
そ。で、その時はスクロールバーを表示しなくちゃいけないから、 この if ブロックの中でスクロールバーの設定をやってるんだ。
スクロールバーの設定ってどんなことするの?
スクロールバーのスライダー(ドラッグして動かせる部分のことね)って、 例えばテキストエディタとかだと、文章の量によって長さが変わるでしょ。
文章が長いとスライダーは短くなるし、逆に文章が短いとスライダーは長くなるよね。
うん、そーだね。
メッセージ履歴画面のスクロールバーもおんなじで、 メッセージの長さによってスライダーの長さが変わるから、 どれくらいの長さにするのかを設定する必要があるわけ。
なるほど。
あと、メッセージのどの位置を表示してるかでスライダーの位置が変わってくるでしょ。
メッセージが横書きの場合だと、例えばメッセージの最初の部分を表示してたら、 スライダーはスクロールバーの一番上に表示されるし、 メッセージの最後の部分を表示してたら、 スライダーはスクロールバーの一番下に表示されるよね。
それも設定する必要があるってこと?
そ。その辺の設定をこの if ブロックの中でやってるの。
じゃ if ブロックの中のスクリプトを見てくね。
最初に scrollBar.maxValdispStart を代入してるみたいだけど、 これって何やってるの?
まず、scrollBar がスクロールバーのオブジェクトってのは覚えてる?
えーっと…スクロールバーのオブジェクトってどこで作ってたんだっけ?
ちょっと前のことになるけど、ExtendedHistoryLayer クラスの makeButtons メソッドでスクロールバーのオブジェクトを作ったよね。
§10.5 参照。
あ、そーだったね。
で、maxVal プロパティについてなんだけど、 ExtendedHistoryLayer クラスの makeButtons メソッドでスクロールバーのオブジェクトを作った時に、minVal ってプロパティが出てきたの覚えてる?
えっと、その辺はあんまりよく覚えてないかな…
じゃもっかい確認しとくね。
minVal プロパティは、 スクロールバーのスライダーが一番上(縦書き表示だと一番右)にある時に、 何行目からの履歴メッセージが表示されるようにするかを設定するプロパティだよ。
makeButtons メソッドのスクリプトには “scrollBar.minVal = 0;” って書いてあるから、 0 に設定してるってことだよね。
つまり、スクロールバーのスライダーが一番上(縦書き表示だと一番右)にある時に、 0 行目以降の履歴メッセージが表示されるわけね。
0 行目って最初の行だよね?
そ。要するに、普通のテキストエディタとかと同じで、 スクロールバーのスライダーが一番上(縦書き表示だと一番右)にある時には履歴メッセージの最初の部分が表示されるってこと。
そっか、なるほどね。
で、maxVal プロパティはその逆で、 スクロールバーのスライダーが一番下(縦書き表示だと一番左)にある時に、 何行目からの履歴メッセージが表示されるようにするかを設定するプロパティなの。
maxVal プロパティには dispStart が代入されてるから、つまりスクロールバーのスライダーが一番下(縦書き表示だと一番左)にある時に dispStart 行目以降の履歴メッセージが表示されるってことだよね?
そうなるね。
dispStart の値はスーパークラス(HistoryLayer クラス)の dispInit メソッドで設定してるから、どんな値になってるかはわかるよね?
dispStart については §10.7 参照。
ん〜っと、確か dispStart の値って everypagetruefalse かで違う意味だったと思うけど、 どっちの場合でも履歴メッセージの最後の部分が表示されるように設定されてたよね?
そ。スクロールできる場合の dispStart の値は、 everypagetrue だと、 履歴メッセージの最後のページが表示されるように “dataPages - 1” になって、 everypagefalse だと、 履歴メッセージの最後の行が画面の一番下(縦書きの場合は一番左)に表示されるように “dataLines - dispLines” になるんだったよね。
ってコトは… もしかして maxVal プロパティを dispStart にすると、 スクロールバーのスライダーが一番下(縦書き表示だと一番左)にある時に履歴メッセージの最後の部分が表示されるってこと?
ん、そういうこと。
こうすれば普通のテキストエディタと同じ感覚でスクロールバーが使えるから使いやすくなるでしょ。
確かにね。
あ、そーいえば、なんで minValmakeButtons メソッドで設定してるのに maxValdispInit メソッドで設定してるの?
履歴メッセージの最初の行は履歴メッセージがどんな長さでも必ず 0 行目になるけど、 履歴メッセージの最後の行が何行目になるかは履歴メッセージの長さによって違うよね。
うん、そーだね。
つまり、minVal プロパティは、 スクロールバーオブジェクトを作った時に一回だけ 0 に設定しとけば、その後設定し直す必要はないんだ。
だから、makeButtons メソッドでスクロールバーオブジェクトを作る時に1回だけ値を設定しとけば OK なの。
じゃあ、maxVal プロパティは履歴メッセージの長さによって値が変わるから、 makeButtons メソッドでスクロールバーオブジェクトを作る時に値を設定するだけじゃダメってこと?
うん、履歴メッセージの長さはメッセージ履歴画面を表示するたびに違ってるかもしれないから、 maxVal プロパティは履歴メッセージ画面を表示するたびに呼び出される dispInit メソッドで設定してるの。
なるほどねぇ。
じゃ次いくね。
次は scrollBar.ratio に何か代入してるみたいだけど、 ratio って何かのプロパティ?
ratio はスライダーの長さを設定するためのプロパティだよ。
値を小さくするとスライダーが短くなって、値を大きくするとスライダーが長くなるってこと?
ん、言い換えると、ratio プロパティの値は履歴メッセージが長いと小さくなって、 履歴メッセージが短いと大きくなるってことだね。
えっと、これって everypagetrue の時と false の時で違う値を代入してるんだよね?
うん。それぞれどんな値を ratio に代入してるかわかる?
ん〜っと…
everypagetrue だったら (1 / dataPages) が代入されて、 everypagefalse だったら (dispLines / dataLines) が代入されるってのはわかるんだけど、代入される値の意味はちょっとよくわかんないかな。
まず、everypagetrue だったらページ単位でメッセージを表示するから、メッセージが何ページあるかでスライダーの長さが決まるの。
だから “1 / dataPages” を代入してるわけね。
何で “1 / dataPages” になるの?
例えば、履歴メッセージが 10 ページあったとしたら dataPages は 10 になるから、“1 / dataPages” は 1 / 10(10分の1)になるよね。
うん。
で、その時スライダーの長さはスクロールバー全体の長さの 10 分の 1 になるの。
※スクロールバーの上下(縦書き表示の場合左右)のボタンの長さは除きます。
あ、そーなんだ。
じゃあ、履歴メッセージが 5 ページあったとしたら、スライダーの長さは?
えっと、スクロールバー全体の長さの 1 / 5 (5分の1)かな。
じゃ履歴メッセージが 2 ページの時のスライダーの長さは?
スクロールバー全体の長さの 1 / 2 (2分の1)だよね。
…って感じで、ratio プロパティに “1 / dataPages” を代入すると、 履歴メッセージのページ数が少なくなるほどスライダーの長さは長くなるわけね。
確かにそうなるね。
テキストエディタとかも同じように、文章の量が少なくなるほどスライダーの長さは短くなるよね。
あ、そっか。それに合わせてるんだね。
そういうこと。
で、everypagefalse の時は、 ページ単位じゃなくって行単位になるから、ratio プロパティの値を “dispLines / dataLines” にしてるの。
それってつまり、行単位でメッセージを表示する時は、 スライダーの長さは “画面に表示できる履歴メッセージの行数÷履歴メッセージ全体の行数” になるってことだよね?
ん。例えば、メッセージ全体が 100 行で、画面に表示できる行数が 16 行だったら、 スライダーの長さはスクロールバー全体の長さの 100 分の 16 になるってことだね。
ちなみに図にするとこんな感じ。

ratio プロパティとスライダーの長さの関係>

特に難しくはないでしょ?
まーね。
で、後はスクロールバーに値を設定するための value プロパティに dispStart の値を代入してるの。
スクロールバーに値を設定するって?
例えば、value プロパティに 0 を代入すると、 スライダーの位置が一番上(縦書きの場合は一番右)に来るの(minVal プロパティを 0 に設定してるからね)。
えっと、じゃあ maxVal プロパティは dispStart になってるから、value プロパティに dispStart を代入したら、スライダーの位置が一番下(縦書きの場合は一番左)に来るってこと?
ん。だからこのスクリプトを実行するってことは、 スライダーの位置を一番下(縦書きの場合は一番左)にしてるってこと。
あ、そっか。
value プロパティに dispStart を代入してるもんね。
メッセージ履歴画面を表示した時は、はじめに履歴メッセージの最後の部分が表示されるから、 スライダーの位置を一番下(縦書きの場合は一番左)にしとく必要があるよね。
だね。
じゃこれで if ブロックの中身は一通りチェックできたね。
後は、最後にスクロールバーの visible プロパティを設定して終わり。
なんで visible プロパティの設定だけ if ブロックの外にあるの?
visible プロパティはスクロールバーを表示する必要がある時に true にするだけじゃなくて、 スクロールバーを表示する必要がない時には false にしなくちゃいけないからだよ。
あ、そーなんだ。
えっと、canScroll は履歴メッセージがスクロールできる時に true になって、スクロールできない時に false になるから、visiblecanScroll の値を代入すると、スクロールできる時は visibletrue になるからスクロールバーが表示されて、 スクロールできない時は visiblefalse になるからスクロールバーは表示されないんだね。
ん、そうそう。
ここまでやればちゃんとメッセージ履歴画面が表示されるってわけだね。
メッセージ履歴画面って一瞬で表示されるからカンタンなのかと思ってたけど、 実はすごい色んなことやってたんだねぇ…
まぁ今まで見てきたのはメッセージ履歴システムのほんの一部なんだけどね。
これでほんの一部なんだ…
さて、まだまだ先は長いけど、とりあえず今回はこの辺にしとこっか。
は〜い。
次回からはマウスとかキーボードとかスクロールバーを使って履歴メッセージをスクロールするためのスクリプトを見ていくことにするね。
それじゃ、また次回!


前へ | TOP | 次へ