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

メッセージ履歴画面を表示してる時に矢印とかのキーを押したりマウスホイールを回したりすると、 履歴メッセージをスクロールできるよね。
そーだね。
今回から、キーを押したりマウスホイールを回したり、あとスクロールバーを操作したりした時に、 履歴メッセージの表示を更新する(スクロールしたり表示するページを切り替えたりするってことね)メソッドを見てくことにするね。
はーい。
じゃあまずどんな操作をしたらどんなふうに履歴メッセージの表示が更新されるかってのを、 横書き表示の時と縦書き表示の時でそれぞれ簡単にまとめとくね。
え、横書き表示の時と縦書き表示の時で操作のやり方が違うの?
ん、キー操作は横書き表示の時と縦書き表示の時でちょっと違ってるよ。
あと everypagetruefalse かでも違ってるね。
じゃあページ単位で履歴メッセージを表示する時と行単位で履歴メッセージを表示する時でもキー操作が違うってこと?
うん。じゃまずは横書き表示の時から見てくね。
everypagetrue の時と false の時でそれぞれこんなふうになってるよ。
<横書きの場合の履歴メッセージ表示更新処理>

everypagetrue の場合)
操作処理呼び出されるメソッド
↑キー,←キー,PageUpキー前のページを表示prevPage
マウスホイールを奥に回転
↓キー,→キー,PageDownキー次のページを表示nextPage
マウスホイールを手前に回転
スクロールバー操作指定されたページを表示setPage

everypagefalse の場合)
操作処理呼び出されるメソッド
↑キー戻る方向にスクロールscrollDown
マウスホイールを奥に回転
←キー,PageUpキー前のページを表示prevPage
↓キー進む方向にスクロールscrollUp
マウスホイールを手前に回転
→キー,PageDownキー次のページを表示nextPage
スクロールバー操作指定された行を表示setLine

この表の見方なんだけど、例えば横書きで everypagetrue の時に ↑キー か ←キー か PageUpキー を押すと、 1つ前のページの履歴メッセージが表示されるって感じね。
あとマウスホイールを奥の方に回転させても前のページの履歴メッセージが表示されるよ。
「前のページを表示」って書いてあるとこの右側に書いてある「prevPage」ってのは?
↑キー か ←キー か PageUpキー を押したり、マウスホイールを奥の方に回転させると、 HistoryLayer クラスの prevPage っていうメソッドが呼び出されて、1つ前のページの履歴メッセージが表示されるって意味だよ。
えっと、じゃあ prevPage ってメソッドが1つ前のページの履歴メッセージを表示するメソッドってこと?
ん、そういうこと。
ちなみに nextPage メソッドも HistoryLayer クラスのメソッドで、1つ先のページの履歴メッセージを表示するメソッドなんだ。
everypagetrue の時に ↓キー か →キー か PageDownキー を押したり、マウスホイールを手前に回転したりした時に呼び出されるメソッドだね。
そ。あとメッセージ履歴画面をカスタマイズしてスクロールバーを付けてるから、 スクロールバーを操作した時に履歴メッセージのページを切り替えるために setPage っていうメソッドを作ってるよ。
それって元々のメッセージ履歴レイヤのクラス(HistoryLayer クラス)にあるメソッドじゃないんだよね?
うん。setPage メソッドはカスタマイズ用に作ったクラスだから、 HistoryLayer クラスじゃなくて ExtendedHistoryLayer クラスのメソッドだよ。
そっか。
じゃ everypagefalse の時も簡単に見とくね。
everypagefalse の時のが操作の種類が多いんだね。
everypagefalse だと行単位で履歴メッセージをスクロール出来るし、 あとページ単位で履歴メッセージを切り替えられるようにもなってるからね。
確かに everypagefalse の方にも「前のページを表示」と「次のページを表示」があるね。
で、行単位で履歴メッセージをスクロールする処理とページ単位で履歴メッセージを切り替える処理は違ってるから、 行単位で履歴メッセージをスクロールするために scrollUp メソッドと scrollDown メソッドがあるんだ。
それって元々のメッセージ履歴レイヤクラスのメソッドなの?
ん、どっちも HistoryLayer クラスのメソッドだよ。
ちなみにスクロールバーを使って行単位で履歴メッセージをスクロールする時には setLine メソッドを使うよ。
これは HistoryLayer クラスじゃなくて ExtendedHistoryLayer クラスのメソッドだよ。
カスタマイズした方のメッセージ履歴レイヤのクラスってことだね。
そう。
で、縦書きの時の方はこんな感じね。
<縦書きの場合の履歴メッセージ表示更新処理>

everypagetrue の場合)
操作処理呼び出されるメソッド
↑キー,→キー,PageDownキー前のページを表示prevPage
マウスホイールを奥に回転
↓キー,←キー,PageUpキー次のページを表示nextPage
マウスホイールを手前に回転
スクロールバー操作指定されたページを表示setPage

everypagefalse の場合)
操作処理呼び出されるメソッド
→キー,PageDownキー戻る方向にスクロールscrollDown
マウスホイールを奥に回転
↑キー前のページを表示prevPage
←キー,PageUpキー進む方向にスクロールscrollUp
マウスホイールを手前に回転
↓キー次のページを表示nextPage
スクロールバー操作指定された行を表示setLine

処理の内容とか呼び出されるメソッドは横書き表示の時と同じみたいだね。
前のページを表示したりするキーがちょっと違ってるのかな?
そ。ちなみにマウス操作とスクロールバー操作は横書きの時と基本的に同じだよ。
そーみたいだね。
それじゃ今回は履歴メッセージのページを切り替えるメソッド、 prevPage メソッドと nextPage メソッドと setPage メソッドを見てくことにするね。
は〜い。
まずこれが prevPage メソッドのスクリプトだよ。

prevPage メソッド(HistoryLayer.tjs から抜粋)>

function prevPage()
{
    // 前ページに移動
    if(!canScroll) return// スクロールできない場合は何もしません
    clearActionHighlights(); // hact タグによるリンク表示を全て消去します
    if(everypage) // ページ単位で履歴メッセージを表示している場合は...
    {
        if(dispStart<1) return// 既に先頭のページを表示している場合は何もしません
        dispStart--; // 表示するページの値を1減らします(1つ前のページを表示します)
        clearBack(); // 現在表示されている履歴メッセージを全て消去します
        drawPage(); // 表示するページの内容をメッセージ履歴レイヤに書き込みます
    }
    else // 行単位で履歴メッセージを表示している場合は...
    {
        clearBack(); // 現在表示されている履歴メッセージを全て消去します
        if(dispStart >= dispLines) // 1ページ前の履歴メッセージが表示できれば...
            dispStart -= dispLines; // 表示する行の値を1ページ(dispLines行)分減らします
        else // そうでなければ...
            dispStart = 0; // 履歴メッセージを最初の行から表示します
        var i;
        for(i = 0 ; i < dispLines; i++)
            drawLine(i); // 各行の履歴メッセージをメッセージ履歴レイヤに書き込みます
    }
    updateButtonState(); // ボタンの表示状態を更新します
}
※コメントを追加しています。

とりあえず最初から見てくね。
まず最初の if のとこで何やってるかはわかるよね?
えっと、“!canScroll” は canScrollfalse の時に真になるんだったと思うから、 canScrollfalse の時、 つまり履歴メッセージがスクロールできない時は return するってことかな?
そう。canScroll は基本的に履歴メッセージが1ページ分しかない時に false になるわけだけど、 履歴メッセージが1ページ分しかなかったら前のページを表示することはできないから、 何もせずに return してるの。
つまり、canScrollfalse だったら何もする必要ないってことだね。
そ。じゃ次いくね。
clearActionHighlights ってメソッドを呼び出してるみたいだけど、 これってどんなメソッドなの?
clearActionHighlights メソッドはリンク表示を消すメソッドだよ。
リンク表示?
hact タグは知ってるよね?
メッセージ履歴画面に表示されてるメッセージがクリックできるようになるタグだよね?
ん、そう。例えば…

hact タグの使用例>

[hact exp="System.inform('履歴メッセージのリンクがクリックされました。')"]
この履歴メッセージにはメッセージ履歴アクションが設定されています。
[endhact]

このスクリプトを実行して、メッセージ履歴画面を表示すると…

<実行画面>

こんなふうに、メッセージのとこがリンクになってクリックできるようになるよね。
そーだね。
ちなみに、このリンクをクリックするとどうなるかわかる?
えっ?
えーっと…どーなるんだっけ?
hact タグで作られたリンクをクリックすると、 hact タグの exp 属性に書いてある TJS スクリプトが実行されるから…
System.inform('履歴メッセージのリンクがクリックされました。')” が実行されるってこと?
そう。
ってことは…?
ってことは、「履歴メッセージのリンクがクリックされました。」って表示されるってこと?
ん、こんな感じだね。

<リンクをクリックした時に表示されるメッセージ>

で、clearActionHighlights メソッドはこのリンクの表示、 つまりメッセージの下に表示されてる下線を消すメソッドなの。
あ、そーなんだ。
ちなみに clearActionHighlights メソッドはカスタマイズしないから、 詳しいスクリプトの説明は省略させてもらうね。
りょーかい。
じゃ次いくね。
ここからは everypagetrue の時と false の時で違う処理をやってるんだけど、 まずは everypagetrue の時の処理から見ていくね。
最初は dispStart1 より小さかったら return してるみたいだね。
なんでだかわかる?
dispStart って今何ページ目を表示してるかを表してるんだったよね?
everypagetrue の時はそうだね。
じゃあ、“dispStart<1” だから、 今表示してるページが1ページ目より前だったら return するってことだよね。
けど、1ページ目って最初のページだから、それより前のページが表示されてることなんてないんじゃないの?
最初のページは1ページ目じゃなくて0ページ目になるから、 1ページ目より前のページが表示されることもあるよ。
あ、そっか。0ページ目から始まるんだっけ。
ってことは、1ページ目より前のページが表示されてるってのは、 最初のページが表示されてることになるんだね。
これで “dispStart<1” の時に何もせずに return する理由がわかったでしょ?
最初のページを表示してたら、1つ前のページを表示できないもんね。
そういうこと。
じゃ次は今表示されてるページが1ページ目以降の時に実行されるスクリプトだね。
最初に “dispStart--;” を実行してるから、 dispStart の値を1減らしてるってことかな。
1つ前のページを表示するから dispStart の値を1減らしてるわけだね。
なるほどね。
えっと、それから clearBack メソッドを呼び出してるね。
clearBack メソッドはどんなメソッドだったか覚えてる?
確か、メッセージ履歴レイヤに表示してるメッセージを消すメソッドだったよね。
ん、ここでは引数を省略して clearBack メソッドを呼び出してるから、 メッセージ履歴レイヤに表示してるメッセージを全部消してるってことだね。
clearBack メソッドについては §10.6 参照。
その後に drawPage メソッドを呼び出してるってことは…
drawPage メソッドは dispStart に設定されてるページの履歴メッセージをメッセージ履歴レイヤに書き込むメソッドだったはずだから、 clearBack メソッドで元々表示されてた履歴メッセージを消して、 それから drawPage メソッドで1つ前のページの履歴メッセージを表示してるってことかな。
drawPage メソッドについては §10.7 参照。
そうそう。
んじゃ次は everypagefalse の時のスクリプトね。
everypagefalse の時は dispStart の値を変える前に clearBack メソッドを呼び出してるんだね。
clearBack メソッドは dispStart の値を参照してないから、dispStart の値を変える前に clearBack メソッドを呼び出しても dispStart の値を変えた後に clearBack メソッドを呼び出しても同じ結果になるよ。
あ、そーなんだ。
次は dispStart の値を更新してるとこだけど、 まず everypagetrue の時と false の時で dispStart の意味が違ってたのは覚えてる?
んーと…everypagetrue の時は今何ページ目を表示してるかを表してて、 everypagefalse の時は今何行目を表示してるかを表してるんじゃなかったかな。
正確に言うと、everypagefalse の時は「今表示してる履歴メッセージの最初の行が(履歴メッセージ全体から見て)何行目の履歴メッセージか」を表してるよ。
※履歴メッセージの一番上の行(縦書き表示の場合は一番右の行)のこと。
あ、そーだったっけ。
じゃ if の条件になってる “dispStart >= dispLines” はどんな時に真になるかわかる?
dispLines ってメッセージ履歴画面に表示できる履歴メッセージの行数だったっけ?
そ。つまり dispLines は1ページ分の履歴メッセージの行数ってことにもなるね。
そっか。じゃあ…今表示してる履歴メッセージの最初の行が1ページ分の履歴メッセージの行数以上だったら真になるってことかな。
んー、まぁそーなんだけど、それちょっとわかりにくい表現だよね。
う〜ん、確かにそーかも…
今表示してる履歴メッセージの最初の行より前に少なくとも1ページ分の履歴メッセージがあるってことだから、 要するに、今表示してるのが1ページ目以降の時に “dispStart >= dispLines” が真になるわけだね。
なるほどねぇ。
まぁこれは図を見た方がわかりやすそうな気がするから、ちょっと図にしてみるね。

<“dispStart >= dispLines” が真の時の動作(dispStart16dispLines16 の場合の例)>

この図は dispLines16 の時に dispStart16 になってる(つまり “dispStart >= dispLines” が真になってる)時の例なんだけど、 prevPage メソッドが呼び出されて “dispStart -= dispLines;” が実行されると、 1ページ前の履歴メッセージが表示されてるでしょ。
えっと、元々1ページ目が表示されてる時に prevPage メソッドが呼び出されると、 1ページ前の0ページ目が表示されるってことなんだよね?
うん、元々 16 行目〜 31 行目(1ページ目)が表示されてて、prevPage メソッドが呼び出されたことで dispStart の値が 16 (=dispLine) 減って 0 行目〜 15 行目(0ページ目)が表示されるってこと。
ふぅん、なるほどね。
で、こっちの図は dispStart14 になってる(つまり “dispStart >= dispLines” が偽になってる)時の例ね。

<“dispStart >= dispLines” が偽の時の動作(dispStart14dispStart < dispLines)の時の例)>

これって元々0ページ目と1ページ目の履歴メッセージがどっちも表示されてるってこと?
everypagefalse の時はどこの行からでも履歴メッセージを表示できるから、 こんなふうに0ページ目の最後の方のメッセージと1ページ目の最初の方のメッセージが表示されることもあるの。
そっか、everypagefalse だとページの区切りは関係ないんだね。
そ。で、この時に prevPage メソッドを呼び出すと、 “dispStart >= dispLines” が偽だから、 ここの else の方が実行されて dispStart0 になるわけだね。
dispStart0 になるってことは、 履歴メッセージの最初の部分が表示されるってことだよね。
そういうこと。
dispStart の値が設定できたら、あとは drawLine メソッドでそれぞれの行の履歴メッセージをメッセージ履歴レイヤに書き込めば OK なわけね。
drawLine メソッドについては §10.8 参照。
結局、everypagetrue でも false でも、dispStart の値を更新してからメッセージ履歴レイヤにメッセージを書き込んでるんだね。
そういうことだね。
で、最後に updateButtonState メソッドを呼び出して「前ページ」と「次ページ」ボタンの表示を更新して終わりだね。
updateButtonState メソッドについては §10.9 参照。
えっと、確か今回はスクロールバーを使うから「前ページ」と「次ページ」ボタンって使わないんだったよね?
ん、だから実際には何もしないってことになるね。
それじゃ次は1つ先のページを表示する nextPage メソッドを見てくね。

nextPage メソッド(HistoryLayer.tjs から抜粋)>

function nextPage()
{
    // 次ページに移動
    if(!canScroll) return// スクロールできない場合は何もしません
    clearActionHighlights(); // hact タグによるリンク表示を全て消去します
    if(everypage) // ページ単位で履歴メッセージを表示している場合は...
    {
        if(dispStart>=dataPages-1) return// 既に最後のページを表示している場合は何もしません
        dispStart++; // 表示するページの値を1増やします(1つ先のページを表示します)
        clearBack(); // 現在表示されている履歴メッセージを全て消去します
        drawPage(); // 表示するページの内容をメッセージ履歴レイヤに書き込みます
    }
    else // 行単位で履歴メッセージを表示している場合は...
    {
        clearBack(); // 現在表示されている履歴メッセージを全て消去します
        if(dispStart < dataLines - dispLines) // 1ページ先の履歴メッセージが表示できれば...
            dispStart += dispLines; // 表示する行の値を1ページ(dispLines行)分増やします
        if(dispStart > dataLines - dispLines) // dispStart + dispLines がメッセージ履歴の終端を超えている場合は...
            dispStart = dataLines - dispLines; // 履歴メッセージの最後の部分を表示するように dispStart の値を調整します
        var i;
        for(i = 0 ; i < dispLines; i++)
            drawLine(i); // 各行の履歴メッセージをメッセージ履歴レイヤに書き込みます
    }
    updateButtonState(); // ボタンの表示状態を更新します
}
※コメントを追加しています。

なんか prevPage メソッドと似てるね。
うん、やってることはほとんど同じだからね。
ってワケだから、nextPage メソッドは prevPage メソッドと違うとこだけチェックしとくね。
りょーかい。
clearActionHighlights メソッドを呼び出すとこまでは prevPage メソッドと同じだから、 ここの if ブロックの中から見てくね。
ちなみにどこが prevPage メソッドと違ってるかわかる?
最初の if の条件が “dispStart>=dataPages-1” になってるとこと、その次の行が “dispStart++;” になってるとこかな。
ん、そうだね。
じゃまずどんな時に “dispStart>=dataPages-1” が真になる?
んー、dataPages は履歴メッセージのページ数だったはずだから、 今表示してるページが dataPages-1 ページ目以降の時に真になるんじゃないかな。
dataPages-1 ページ目は最後のページになるから、 今表示してるページが dataPages-1 ページ目以降ってことは…?
最後のページを表示してる時ってことかな?
そういうことだね。
最後のページを表示してる時は次のページがないから、何もせずに return してるわけだね。
そっか。なるほどね。
じゃその次の行の “dispStart++;” は?
次のページを表示するから dispStart の値を1増やしてるんだよね。
ん、そうそう。後の処理は prevPage メソッドの時と同じだから問題ないよね。
んじゃ次は else ブロックの中身を見てくね。
なんか if の条件が prevPage メソッドの時よりちょっと複雑になってるね。
まぁこれも prevPage メソッドの時とやってることは似てるんだけどね。
とりあえず “dispStart < dataLines - dispLines” がどんな時に真になるかわかる?
確か dataLines って履歴メッセージ全体の行数だったよね?
そうだよ。
じゃあ…今表示してる履歴メッセージの最初の行が “履歴メッセージ全体の行数−1ページ分の履歴メッセージの行数”より小さいってことだから…
一番最後のページより前のページの履歴メッセージを表示してる時、ってことになるのかな?
ん、そういうこと。
つまり、一番最後以外のページを表示してる時に “dispStart += dispLines;” が実行されるわけだね。
ちなみに図にするとこんな感じ。

<“dispStart < dataLines - dispLines” が真の時の動作(dispStart0dispLines16dataLines34 の時の例)>

で、後もう一つ if があるんだけど、 こっちは何やってるかわかる?
今度は “dispStart > dataLines - dispLines” だから、今表示してる履歴メッセージの最初の行が “履歴メッセージ全体の行数−1ページ分の履歴メッセージの行数”より大きい時に “dispStart = dataLines - dispLines;” が実行されるってことだよね。
だね。
これって言い換えると “今表示してる履歴メッセージの最初の行と1ページ分の履歴メッセージの行数を足すと履歴メッセージ全体の行数より大きくなる (dispStart + dispLines > dataLines)” ってことだよね?
でも履歴メッセージ全体の行数より大きくなることってあるの?
そうならないようにするために、この if があるの。
えっ、どーゆーコト?
例えば、dispStart14 の時に “dispStart += dispLines;” を実行すると…

dispStart14 の時に “dispStart += dispLines;” を実行した時の状態>

dispStart30 になって “今表示してる履歴メッセージの最初の行(30)と1ページ分の履歴メッセージの行数(16)を足すと履歴メッセージ全体の行数(34)より大きくなる” から、 表示するメッセージが無い部分が出来ちゃうわけね。
うん、そーなるよね。
そうならないように、 今表示してる履歴メッセージの最初の行と1ページ分の履歴メッセージの行数を足すと履歴メッセージ全体の行数より大きくなってる時には、 ここの if のとこで “dispStart = dataLines - dispLines;” を実行してるの。
そうすれば…

この if ブロックを実行した後の状態>

こんなふうに、ちゃんと履歴メッセージの最後の部分が表示されるの。
えっと、つまり最初の if で “dispStart += dispLines;” が実行されて dispStart の値が大きくなり過ぎちゃった時は、 2つ目の if で履歴メッセージの最後の部分が表示されるように dispStart の値を調整してるってことかな?
そういうことになるね。
これで dispStart にちゃんとした値が設定されたから、 後は drawLine メソッドで1行ずつ履歴メッセージをメッセージ履歴レイヤに書き込んでるわけね。
これは prevPage メソッドの時とおんなじだね。
ん。で最後に updateButtonState メソッドでボタンの状態を更新して終わり。
これも prevPage メソッドと同じだね。
そ。
じゃこれで nextPage メソッドは一通りチェックできたから、 最後にスクロールバー用の setPage メソッドを見てくね。

setPage メソッド>

function setPage(page)
{
    if(dispStart == page)
        return// 既に表示されているので何もしません
    clearActionHighlights(); // メッセージ履歴アクションのハイライト表示を消去します
    dispStart = page; // 表示開始位置を更新します
    clearBack(); // 現在表示されている履歴メッセージを全て消去します
    drawPage(); // このページの内容(メッセージ履歴テキスト)を書き込みます
}

意外とシンプルだねぇ…
まぁね。
じゃ setPage メソッドがどんな処理をやってるか説明してみて。
ちなみに引数の page は表示するページ番号になってるよ。
※スクロールバーが操作されると setPage メソッドが呼び出されます。その際にスクロールバーオブジェクトによって page の値が与えられます。
えっと、まず最初の if のとこで dispStartpage と同じ値だったら return してるね。
なんでだかわかる?
dispStartpage がおんなじってことは、 元々 page のページが表示されてたってことだから、 別にページを切り替える必要がないってことなんじゃない?
そうそう。
じゃ次いこっか。
次は clearActionHighlights メソッドを呼び出してるね。
これは prevPage メソッドとか nextPage メソッドでも呼び出してたよね。
だね。
次は dispStartpage を代入してるね。
dispStart に表示するページを設定した後で clearBack メソッドと drawPage メソッドを呼び出せば、 設定したページの履歴メッセージが表示されるんだよね?
ん、そういうこと。
このメソッドは特に問題ないでしょ?
うん。
それじゃ今回はここまでにしとくね。
は〜い。
次回はマウスホイールとかでメッセージ履歴をスクロールする時に呼び出されるメソッドを見てくことにするね。
それじゃ、また次回ね!


前へ | TOP | 次へ