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

今回から本格的にメッセージ履歴表示をカスタマイズしていくね。
まず、このフローチャートは覚えてる?
<メッセージ表示に関係する部分の処理の流れ(再掲)>
これって前回出てきたメッセージ履歴表示の流れの図だよね?
そ。これだけ見ると結構シンプルそうに見えるんだけど…
うん?
この図に、それぞれの処理で呼び出されるメソッドとかを書き込んでみると…
<メッセージ表示に関係する部分の各処理で呼び出されるメソッドと設定されるプロパティ>
こんな感じになるの。
うわ、すごいフクザツになってる…
まぁこれでもカスタマイズしてる部分の一部なんだけどね。
なんか今回もタイヘンそーだねぇ…
さすがにこれをいっぺんに見てくのはムリだから、 まず最初は dispInit メソッドから始めることにするね。
それってどんなメソッドなの?
dispInit メソッドは、 メッセージ履歴画面が表示される時に呼び出されるメソッドなんだ。
じゃあメニューの「メッセージ履歴の表示」を実行した時とかに呼び出されるってこと?
そうそう。
あと、R キーとか Shift+↑ キーを押したり、マウスホイールを奥の方に回したり、 それから showhistory タグを実行したりしても呼び出されるね。
※デフォルト設定の場合。
そーいえば、メッセージ履歴画面を表示する方法って色々あるよね。
メニューの「メッセージ履歴の表示」を実行した時に kag オブジェクト(KAGWindow クラス)の onShowHistoryMenuItemClick メソッドが呼び出されるってのは覚えてる?
えっと、そーだったっけ?
まぁ前にシステムボタンプラグインを作った時に1回出てきただけだから、 忘れちゃってるのも無理ないかもだけどね。
§5.10 参照。
あ〜、確かメッセージ履歴画面を表示したりメッセージをスキップしたりするのに on何とかMenuItemClick ってメソッドをいくつか呼び出してたよね。
その on何とかMenuItemClick ってメソッドの中で、 メッセージ履歴画面を表示するのが onShowHistoryMenuItemClick メソッドなわけね。
で、onShowHistoryMenuItemClick メソッドは KAGWindow クラス(kag オブジェクトのクラスのことね)の中で、 こんなふうに定義されてるんだ。

onShowHistoryMenuItemClick メソッド(MainWindow.tjs より抜粋)>

function onShowHistoryMenuItemClick(sender)
{
    if(historyLayer.visible) hideHistory(); else showHistory();
}

このメソッドを呼び出すとどうなるかはわかるよね?
historyLayer.visibletrue だったら hideHistory っていうメソッドが呼び出されて、 historyLayer.visiblefalse だったら showHistory っていうメソッドが呼び出されるのかな?
そ。ちなみに historyLayer.visible はメッセージ履歴レイヤの visible プロパティだから、 メッセージ履歴画面が表示されてたら true、 表示されてなかったら false になってるよ。
じゃあ、メッセージ履歴画面が表示されてたら hideHistory メソッドが呼び出されて、 表示されてなかったら showHistory メソッドが呼び出されるんだね。
そういうこと。
つまり、showHistory メソッドを呼び出すとメッセージ履歴画面が表示されるってことだね。
だね。
で、showHistory メソッドはこんなふうに定義されてるの。

showHistory メソッド(MainWindow.tjs より抜粋)>

function showHistory()
{
    // メッセージ履歴レイヤを表示する
    historyLayer.parent = fore.base; // メッセージ履歴レイヤの親も再設定
    historyLayer.absolute = 2000000; // メッセージ履歴レイヤの重ね合わせ順序を再設定
    historyLayer.dispInit(); // メッセージ履歴レイヤを表示します
    historyShowing = true// メッセージ履歴レイヤが表示されていることを表すフラグをセットします
    if(typeof this.showHistoryMenuItem != "undefined"// 「メッセージ履歴の表示」メニューが存在していれば…
        showHistoryMenuItem.checked = true// 「メッセージ履歴の表示」メニューにチェックを入れます
    setMenuAccessibleAll(); // 各メニュー項目の使用可/不可(enabled プロパティ)を設定します
}
※コメントを追加しています。

showHistory メソッドの中で dispInit メソッドが呼び出されてるでしょ。
ホントだ。
historyLayer.dispInit();”って書いてあるね。
ってワケだから、メニューの「メッセージ履歴の表示」を実行すると、メッセージ履歴画面が表示されるの。
ただ、メッセージ履歴画面が既に表示されてる状態でメニューの「メッセージ履歴の表示」を実行すると hideHistory メソッドの方が呼び出されるから、逆にメッセージ履歴画面が非表示になるけどね。
なるほどね〜。
あと、キーやマウスホイールの操作でメッセージ履歴画面を表示したり、 showhistory タグでメッセージ履歴画面を表示したりする時も showHistory メソッドが呼び出されるようになってるよ。
そーなんだ。
じゃこれで dispInit メソッドがどんな時に呼び出されるかは大体わかったと思うから、 次は dispInit メソッドでメッセージ履歴画面を表示する処理の流れを見てくね。
えっと、確かメッセージ履歴画面を表示するのって、 メッセージ履歴表示用のレイヤの visibletrue にして表示状態にするって言ってたよね?
うん。だけどそれだけじゃなくって、他にも色んなことをやってるんだ。
ちなみに、元々のメッセージ履歴レイヤ(カスタマイズする前の普通のメッセージ履歴レイヤのことね)の dispInit メソッドだけでも、これだけの処理をやってるよ。

<元々のメッセージ履歴レイヤ(HistoryLayer クラス)の dispInit メソッドの処理の流れ>

※今回のカスタマイズに直接関係のない処理は省略しています。

確かに色々やってるみたいだね。
じゃ最初から簡単に見てくね。
dispInit メソッドが呼び出されたら、 まず最初に「前ページ」「次ページ」「閉じる(×)」の3つのボタンを作るんだ。
処理の流れ図の STEP 1 参照。
ボタンって最初からあるわけじゃなくて、 メッセージ履歴画面を表示する時に作るんだ?
ん、メッセージ履歴レイヤのオブジェクトを作る時じゃなくて、 一番始めにメッセージ履歴画面を表示する時にこの3つのボタンが作られるの。
ちなみにメッセージ履歴画面を閉じても(非表示にしても)ボタンのオブジェクトは無効化されないから、 ボタンが作られるのは最初にメッセージ履歴画面を表示した時だけで、 2回目からはメッセージ履歴画面を表示してもボタンを作る必要ないんだ。
へぇ、そーなんだ。
ボタンを作る処理は makeButtons っていうメソッドの中でやってるんだけど、詳しくはまた後で見てくね。
で、次に clearBack っていうメソッドを呼び出して、 メッセージ履歴画面に表示されてる履歴メッセージを全部消すんだ。
処理の流れ図の STEP 2 参照。
え? まだなんにもメッセージを書き込んでないから、 メッセージを消す必要なんてないんじゃないの?
確かに、最初にメッセージ履歴画面を表示する時はそうなんだけどね。
メッセージ履歴画面を非表示にしても、それまで表示してた履歴メッセージは消えないようになってるから、 ここで履歴メッセージを消しとかないと、2回目以降にメッセージ履歴画面を表示した時に、 前に表示してた履歴メッセージが残っちゃうんだ。
あ、そーなんだ。
で、(前に表示されてた)履歴メッセージを消した後に、 今回表示する履歴メッセージをメッセージ履歴レイヤに書き込むわけだけど、 メッセージを書き込む時には everypagetrue になってる時と false になってる時で別々の書き込み処理が実行されるようになってるんだ。
処理の流れ図の STEP 3 参照。
everypage って?
Config.tjs で設定できる everypage のことだよ。

everypage の設定箇所(Config.tjs より抜粋)>

// ◆ ページ単位での閲覧を行うかどうか
// ページ単位での閲覧をするようになると
// cm ct er タグ、あるいは repage 属性が true の hr タグ
// でメッセージ履歴の改ページを行うようになります。
;everypage = false;

あー、これって確か true にするとメッセージ履歴がページごとに表示されるようになるんだよね?
そ。everypagetrue にするか false にするかでメッセージ履歴表示処理が結構変わってくるんだ。
そーなの? 見た目にはそんなに違わないよーに見えるけど。
そーなの。
ま、詳しくはまた後で見てくことにするね。
んで履歴メッセージの書き込みが終わったら、 次は「前ページ」と「次ページ」ボタンの状態を更新するんだ。
処理の流れ図の STEP 4 参照。
ボタンの状態を更新するって?
「前ページ」「次ページ」ボタンの文字の色って、 履歴メッセージがスクロールできる時とスクロールできない時で違ってるでしょ。

<「前ページ」「次ページ」ボタンの文字色(横書きで everypagefalse の場合)>

こんなふうに、スクロールできる時はボタンの文字の色が赤色になってて、 スクロールできない時は文字の色が暗くなってるよね。
そーいえばこんなふうに表示されてるね。
あと、スクロールできる時はボタンオブジェクトの enabled プロパティを true にしてボタンを使える(クリックできる)ようにする必要があるし、 逆にスクロールできないときは enabled プロパティを false にしてボタンを使えないようにする必要もあるよね。
確かにそーだね。
つまり、ボタンの状態を更新するってのは、ボタンの文字の色とか enabled プロパティの値を設定するってことなわけね。
なるほどね。
ボタンの状態の更新は updateButtonState っていうメソッドでやるんだけど、 これも詳しくはまた後で見てくことにするね。
で、最後にメッセージ履歴レイヤの visible プロパティを true に設定するの。
処理の流れ図の STEP 5 参照。
やっと visible プロパティが出てきたね。
visible プロパティを設定するのは一番最後だからね。
これが元々のメッセージ履歴レイヤ(HistoryLayer クラス)の dispInit メソッドの大体の流れね。
で、今回はこれをカスタマイズするから…
もっとややこしくなる、ってこと?
ううん、やることはちょっと変わってくるけど、 別にそんなにややこしくはならないよ。
そーなの?
うん。
カスタマイズしたメッセージ履歴レイヤ(ExtendedHistoryLayer クラス)の dispInit メソッドの処理の流れはこんな感じだよ。

<カスタマイズしたメッセージ履歴レイヤ(ExtendedHistoryLayer クラス)の dispInit メソッドの処理の流れ>

※今回のカスタマイズに直接関係のない処理は省略しています。

元々のメッセージ履歴レイヤの dispInit メソッドの処理の流れとそんなに変わらないでしょ。
そーだね…なんかステップが1つ増えてるみたいだけど。
とりあえず、元々のメッセージ履歴レイヤの dispInit メソッドと違うとこだけ確認しとくね。
はーい。
まず、カスタマイズしたメッセージ履歴レイヤでは「前ページ」「次ページ」ボタンの代わりにスクロールバーを使うから、 最初に「前ページ」「次ページ」ボタンじゃなくてスクロールバーを作るんだ。
あと、「閉じる(×)」ボタンは画像を設定できるように拡張したボタンにしてるよ。
処理の流れ図の STEP 1 参照。
じゃあカスタマイズしたメッセージ履歴画面を表示する時には「前ページ」ボタンとか「次ページ」ボタンは作らないってこと?
ん、そうなるね。
で、次の履歴メッセージを消す処理(STEP 2)と最初に表示される履歴メッセージを書き込む処理(STEP 3-1/3-2)は、 元々のメッセージ履歴レイヤとおんなじだよ。
その次のボタンの状態更新のとこ(STEP 4)は元々のメッセージ履歴と違ってるね。
「なにもする必要なし」って書いてあるけど…?
処理の流れ図の STEP 4 参照。
うん、ボタンの状態更新処理は必要ないんだ。
え、ホントに?
「前ページ」「次ページ」ボタンは使ってないし、「閉じる(×)」ボタンの状態は特に更新する必要ないからね。
あ、そー言われれば確かに何もすることないね。
でしょ。
で、次は(STEP 5 で)メッセージ履歴レイヤの visible プロパティを true にして…
これは元々のメッセージ履歴レイヤとおんなじだね。
ん。元々のメッセージ履歴レイヤだとここまでで終わりなんだけど、 カスタマイズしたメッセージ履歴レイヤにはスクロールバーがあるから、 最後にスクロールバーの状態を更新する必要があるんだ。
処理の流れ図の STEP 6 参照。
スクロールバーの状態更新って何やるの?
基本的にスライダーの長さと位置の設定だね。
ちなみにスライダーってのはコレのことね。

<履歴メッセージの長さ・表示位置によるスクロールバーの表示の違い(横書きの場合)>

履歴メッセージ全体が短いとスライダーは長くなるし、 逆に履歴メッセージ全体が長いとスライダーは短くなるよね。
あと、履歴メッセージの最初の方を表示してる時はスライダーは上のほうにあるし、 逆に履歴メッセージの最後の方を表示してる時はスライダーは下のほうにあるよね。
それって自動的に設定されないの?
自動的に設定できれば便利なんだろうけどね。
残念ながらこのスクロールバーの場合は手動で設定しなくちゃいけないの。
そーなんだ。
元々のメッセージ履歴画面表示とカスタマイズしたメッセージ履歴画面表示の違いは大体こんなとこだね。
で、ここからがちょっとややこしい話になるんだけど…
えっ?
さっき、カスタマイズしたメッセージ履歴レイヤの dispInit メソッドの処理の一部は、 元々のメッセージ履歴レイヤの dispInit メソッドの処理とおんなじって言ったよね。
うん。
ExtendedHistoryLayer クラス(カスタマイズしたメッセージ履歴レイヤ)は HistoryLayer クラス(元々のメッセージ履歴レイヤ)を継承して作るわけだけど、 その時に元々のメッセージ履歴レイヤと違う処理をする部分は ExtendedHistoryLayer クラス側で処理して、 元々のメッセージ履歴レイヤと同じ処理をする部分は HistoryLayer クラス側で処理するんだ。
えっと、よくわかんないんだけど…?
…だよね。
言葉で説明するのはちょっと難しいから、図にしてみるね。
まずこの図を見てみて。

<カスタマイズしたメッセージ履歴レイヤ(ExtendedHistoryLayer クラス)での dispInit メソッドの実際の処理の流れ>

うわ、なんかすごいフクザツな図…
一見複雑に見えるけど、左側と右側にそれぞれ元々のメッセージ履歴レイヤの dispInit メソッドの流れ図と、カスタマイズしたメッセージ履歴レイヤの dispInit メソッドの流れ図を並べてるだけだよ。
あ、ホントだ。
…でも矢印のつながり方は複雑だよね?
それも一見複雑そうだけど、実際にはそうでもないよ。
ほんとに?
まず最初に STEP 1 でボタンとかを作る時だけど、 カスタマイズしたメッセージ履歴画面には「前ページ」ボタンとか「次ページ」ボタンは表示しないから、 HistoryLayer クラスの方じゃなくて ExtendedHistoryLayer クラスの方の STEP 1 を実行するわけね。
ちなみに HistoryLayer クラスの STEP 1 が薄く表示されてるのは、 こっち側の STEP 1 は実行しないよ、って意味だよ。
あ、そーいう意味だったんだ。
で、STEP 2 の履歴メッセージを消す処理と STEP 3-1/3-2 の履歴メッセージを書き込む処理は、 カスタマイズしても変わらないから、HistoryLayer クラスの STEP 2 と STEP 3-1/3-2 の方を実行するわけね。
えっと、じゃあ ExtendedHistoryLayer クラスの STEP 2 と STEP 3-1/3-2 は実行されないから薄く表示されてるってことだよね?
そうそう。
それから、ボタンの表示状態を更新する必要はないから、STEP 4 は ExtendedHistoryLayer クラスの方を実行するの。
visible プロパティを true にするのはカスタマイズしても変わらないから STEP 5 は HistoryLayer クラスの方が実行されるってことだね。
そ。で最後の STEP 6 は ExtendedHistoryLayer クラスにしかない処理だから、 ExtendedHistoryLayer クラスの STEP 6 が実行されるの。
要するに、それぞれのステップの処理に応じて HistoryLayer クラス側で処理するか ExtendedHistoryLayer 側で処理するかを決めてるってこと。こうすれば効率的に処理できるからね。
なるほどねぇ…
結局、この図を見るとわかると思うけど、 メッセージ履歴レイヤをカスタマイズするためには、 dispInit メソッドの STEP 1 と 4 と 6 の部分を新しく作ればいいってことね。
そっか。STEP 2 と 3-1/3-2 と 5 の部分は、元々のメッセージ履歴レイヤでやってるのとおんなじ処理だから作る必要ないんだね。
そういうこと。
じゃ今回はこの辺にして、次回は dispInit メソッドのスクリプトを見てくことにするね。
は〜い。
それじゃ、また次回ね!


前へ | TOP | 次へ