今回は everypage が false の時、つまり行単位で履歴メッセージを表示する場合に、スクロールバーを操作した時に呼び出される setLine メソッドを見てくね。 | |
えっと、それも前回やった scrollUp メソッドとか scrollDown メソッドみたいに、 履歴メッセージをスクロール表示するためのメソッドなんだよね? | |
そだよ。 scrollUp メソッドとか scrollDown メソッドは1行ずつ履歴メッセージをスクロール表示するメソッドだったわけだけど、 スクロールバーの場合は一度に何行もスクロールしなくちゃいけなくなることもあるから、 専用のメソッドを作ることにしたんだ。 |
|
じゃあ setLine メソッドって一度に何行もスクロールできるメソッドなんだ? | |
まぁそういうことだね。 setLine メソッドは、 スクロールできる範囲ならどの行からでも履歴メッセージを表示できるメソッドだからね。 |
|
へぇ、そーなんだ。 | |
それじゃ、setLine メソッドのスクリプトを見てくね。 |
長っ! | |
まぁ setLine メソッドは HistoryLayer クラスの prevPage メソッドと nextPage メソッドと scrollUp メソッドと scrollDown メソッドを合わせたようなメソッドだからね。 | |
※prevPage, nextPage メソッドについては §10.10、 scrollUp, scrollDown メソッドについては §10.11 参照。 | |
え、そーなの? それだけのメソッドを合わせてたらそりゃ長くもなるよね… |
|
ま、見た目は長いけど、やってることは prevPage メソッドとか scrollUp メソッドに似てるから、ちょっとはわかりやすいんじゃないかな。 | |
そーなの? | |
うん。 じゃとりあえず最初から見てくね。 |
|
最初の if のとこで
dispStart と line の値が同じかどうかチェックしてて、
同じだったら何もせずに return してるね。 dispStart は、今表示してる履歴メッセージの一番最初の行が履歴メッセージ全体で何行目かを表してる値だけど、 setLine メソッドの引数になってる line ってどんな値なの? |
|
line は、スクロール後の履歴メッセージの一番最初の行が履歴メッセージ全体で何行目かってのを表してる値だよ。 つまり、setLine メソッドが呼び出された後は、 履歴メッセージの一番最初の行が履歴メッセージ全体で line 行目になるってことね。 |
|
じゃあ、dispStart と line の値がおんなじってことは… 今表示してる履歴メッセージの最初の行(dispStart)と、 スクロール後の履歴メッセージの最初の行(line)がおんなじってことになるから、 何もする必要ないってこと? |
|
ん、そういうこと。 それじゃ次いこっか。 |
|
line - dispStart を diff って変数に代入してるね。 | |
“line - dispStart” がどんな値になるかはわかる? | |
えっと…スクロール後の履歴メッセージの最初の行から、 今表示してる履歴メッセージの最初の行を引いた値ってことだよね…? | |
そ。 | |
うーん…それって何の値になるんだろ…? | |
例えば、今表示してる履歴メッセージの最初の行(dispStart)が3行目で、 スクロール後の履歴メッセージの最初の行(line)が10行目だとすると、 diff の値は? | |
10 - 3 だから 7 になるよね。 | |
じゃ、今表示してる履歴メッセージの最初の行が3行目で、 10行目からの履歴メッセージを表示したい時には、 何行先にスクロールすればいいと思う? | |
7行だね。 | |
これで diff がどんな値かわかったでしょ? | |
あ、もしかして diff って何行先にスクロールするかを表してる変数ってこと? | |
そういうこと。 ちなみに、さっきとは逆に、今表示してる履歴メッセージの最初の行が10行目で、 スクロール後の履歴メッセージの最初の行が3行目だとすると、 diff の値は? |
|
それだと 3 - 10 で -7 になるね。 | |
この場合は、7行前のメッセージを表示することになるよね。 | |
そだね。 | |
つまり、diff の値がプラスだと先の履歴メッセージを表示して、 マイナスだと前の履歴メッセージを表示するって意味なのね。 | |
じゃあ diff が 7 だと7行先にスクロールして、 -7 だと7行前にスクロールするってことなんだね。 | |
そう。 じゃ次の if ブロックのとこで何をチェックしてるかわかる? |
|
“diff <= -dispLines || diff >= dispLines”って条件だから、 diff の値が -dispLines 以下になってるか、dispLines 以上になってれば if ブロックの中が実行されるってことだよね。 | |
そうだね。 | |
-dispLines って dispLines の値のマイナスってこと? | |
そうだよ。 例えば dispLines が 5 だったら -dispLines は -5 になるよ。 |
|
え〜っと…じゃあ dispLines 以下の行数分前にスクロールするか、 dispLines 以上の行数分先にスクロールする時に if ブロックの中が実行されるってことかな? | |
ん〜、ちょっと違うねー。 | |
えっ、違うの? | |
例えば dispLines が 10 だとしたら、 lines が -10 以下の時か 10 以上の時に if ブロックの中が実行されるよね。 | |
そーだね。 | |
-10 以下ってことは -10 とか -11 とか -12 とかってことだし、 10 以上ってことは 10 とか 11 とか 12 とかってことだよね。 | |
うん。 | |
10 とか 11 とか 12 の時は dispLines 以上の行数分先にスクロールするってのは合ってるんだけど… | |
うん? | |
-10 の時は10行前にスクロールするってことだし、 -11 の時は11行前にスクロールするってことだから、 “dispLines 以下の行数分前にスクロールする”ってのはおかしいでしょ? | |
あ、そっか。確かにそーだね。 それじゃあ、dispLines 以下じゃなくて、 dispLines 以上の行数分前にスクロールするってことかな? |
|
ん、そう。 つまり、“diff <= -dispLines || diff >= dispLines”は、“dispLines 行以上前か先にスクロールする”場合に真になるってことだね。 |
|
なるほどね。 | |
ところで、dispLines ってどんな値だった? | |
メッセージ履歴画面に表示できる履歴メッセージの行数だよね? つまり、1ページ分の履歴メッセージの行数ってことになるのかな。 |
|
ってことは、dispLines 行以上前か先にスクロールすると、 スクロールする前に表示されてた履歴メッセージは全部画面の外に出ちゃうよね。 | |
メッセージ履歴画面に表示できる履歴メッセージの行数分以上前か先にスクロールするってことだから、 確かにそうなるね。 | |
だから、ここの if ブロックの中では、 メッセージ履歴画面に表示されてる履歴メッセージを全部書き換えてるんだ。 | |
そーなんだ。 | |
最初に clearBack メソッドを呼び出してるでしょ。 | |
※clearBack メソッドについては §10.6 参照。 | |
うん。 | |
引数なしで clearBack メソッドを呼び出すとどうなるんだった? | |
画面に表示されてる履歴メッセージを全部消すんじゃなかったっけ? | |
そう。で、clearBack メソッドで履歴メッセージを全部消した後、 ここの for ループで drawLine メソッドを呼び出して、 スクロールした後の履歴メッセージを全部書き込んでるんだけど、 ここの for ループがどんなふうに実行されるかわかる? | |
※drawLine メソッドについては §10.8 参照。 | |
えっと…i が 0 から始まって、 dispLines より小さい間ループするから、 drawLine(0), drawLine(1), drawLine(2), ... , drawLine(dispLines - 1) っていう順番で、全部で dispLines 回 drawLine メソッドが呼び出されるのかな? | |
ん。つまり、(横書き表示の場合だと)上から順番に1行ずつ履歴メッセージを書き込んでいくわけだね。 この部分は everypage が false の時の HistoryLayer クラスの prevPage メソッドと nextPage メソッドの処理に似てるでしょ。 |
|
確かに、どっちも clearBack メソッドを呼び出して、 dispStart の値を設定して、 drawLine メソッドで履歴メッセージを書き込んでるってとこがおんなじだね。 | |
prevPage メソッドと nextPage メソッドもメッセージ履歴画面全体を書き換える必要があるからね。 | |
そっか、だから似てるんだね。 | |
それじゃ次はここの else if のブロックを見てくね。 | |
条件が “diff > 0” ってことは、 このブロックは履歴メッセージを先の方にスクロールする時に実行されるってことだよね? | |
そう。 このブロックは HistoryLayer クラスの scrollUp メソッドに似てるでしょ? |
|
ん〜、そー言われると似てるような感じもするかな。 こっちには最後の方に for ループがあったりしてちょっと違ってるみたいだけど。 |
|
scrollUp メソッドの時は1行だけ先にスクロールしてたでしょ。 | |
そだね。 | |
ここの else if ブロックの方は、 複数行先にスクロールすることもできるようになってるの。 | |
それって diff が 2 以上だったら 2 行以上先にスクロールしなくちゃいけないからなんだよね? | |
そう。 scrollUp メソッドと違うのはそれだけで、やってることは scrollUp メソッドと同じなんだ。 |
|
あ、そーなんだ。 | |
じゃここの else if ブロックでやってることを簡単にチェックしとくね。 | |
はーい。 | |
diff の値(つまりスクロールする行数だね)によってちょっと処理が違ってくるんだけど、 まぁどんな値になってても基本的な処理は変わらないから、とりあえず diff が 4 の時の処理の流れを見てくことにするね。 | |
diff が 4 ってことは、 4行先にスクロールするってことだね。 | |
そ。あと、今回は横書きの時の処理だけ見てくね。縦書きの時の処理は
scrollUp
メソッドを参照ってことで。 それから、dispLines は 10 ってことにしとくね。 |
|
りょーかい。 | |
最初の clearActionHighlights メソッドはわかるよね。 | |
hact タグで表示されるリンクを消すメソッドだね。 | |
ん。じゃ次は copyRect メソッドを呼び出してるとこね。 横書き表示(verticalView が false)の時の処理を見てくから else ブロックの方だね。 |
|
※copyRect メソッドについては §4.4 参照。 | |
scrollUp メソッドで copyRect メソッドを呼び出してたとこと似てるけど、引数がちょっと違ってるみたいだね。 | |
まぁ複数行スクロールできるようになってるからね。 これは前と同じように図にしてみた方が良さそうだね。 |
|
そーだね。スクリプトだけじゃわかりにくいもんね。 | |
まず、これがコピー元の四角形領域だよ。 |
<4行先の方にスクロールする場合(diff が 4 の場合)の copyRect メソッドでのコピー元領域>
scrollUp メソッドの時のコピー元領域と比べてみると、違いがよくわかると思うよ。 | |
scrollUp
メソッドの時は一番上の1行以外がコピー元になってたけど、
こっちの方は上から4行分以外のとこがコピー元になってるね。 これってスクロールする行数が4行だからこうなってるの? |
|
ん、そうだよ。 だからスクロールする行数が3行だったら、上から3行分以外のとこがコピー元になるし、 2行スクロールするんだったら、上から2行分以外のとこがコピー元になるわけね。 |
|
なるほどね。 | |
んじゃ次はコピー先を見てみるね。 |
<4行先の方にスクロールする場合(diff が 4 の場合)の copyRect メソッドでのコピー先領域>
これも scrollUp メソッドの時のコピー先領域と比べてみるとわかりやすいんじゃないかな。 | |
scrollUp
メソッドの時は一番下の1行以外がコピー先になってたけど、
こっちの方は下から4行分以外のとこがコピー元になってるね。 これもスクロールする行数が4行だからこうなってるんだよね? |
|
そう。特にわかりにくくはないでしょ? | |
まーね。 | |
で、copyRect メソッドを呼び出した後はこうなるよね。 |
じゃ次いくね。 | |
clearBack メソッドを呼び出してるみたいだけど、 for ループがあるから、 何回か繰り返し呼び出してるってことだよね。 | |
diff が 4 だったら何回呼び出される? | |
んーと、diff が 4 だと “for(i=1;i<=4;i++)” になって、i が 1, 2, 3, 4 の時に clearBack メソッドが呼び出されるから、4回だね。 | |
clearBack メソッドは、 引数を指定するとその行の履歴メッセージを消すから、 この for ループで4行分の履歴メッセージを消してるってわけだね。 | |
これも4行スクロールするからなの? | |
そ。この図見るとわかると思うけど、 4行先にスクロールすると、 下から4行分の“6行目のメッセージ” 〜 “9行目のメッセージ”の部分は、 “10行目のメッセージ” 〜 “13行目のメッセージ”にならなくちゃいけないでしょ。 | |
そっか。だから下から4行分のメッセージを消さなきゃいけないんだね。 えっと、i が 1, 2, 3, 4 の時に、clearBack メソッドの引数は dispLines - 1, dispLines - 2, dispLines - 3, dispLines - 4 になるから、これで下から 1, 2, 3, 4 行目のメッセージが消せるってことかな。 |
|
そう。clearBack メソッドを呼び出した後はこうなるよね。 |
んで次にさっき消したとこに10〜13行目のメッセージを書き込んでいくの。 ま、その前に dispStart に line の値を代入する必要があるけどね。 |
|
確か drawLine メソッドで履歴メッセージを書き込む前に、 dispStart に一番上に表示される履歴メッセージの行の番号を代入しとかなくちゃいけないんだったよね? | |
そ。それから drawLine メソッドを呼び出すわけね。 | |
今度も for ループになってるけど、 これってさっきの for ループで “clearBack” になってたとこが “drawLine” に変わっただけみたいだね。 | |
まぁ clearBack メソッドで履歴メッセージを消したとこに書き込むわけだからね。 | |
あ、そっか。 | |
これで10〜13行目の履歴メッセージがこんなふうに書き込まれて、スクロール完了だね。 |
<drawLine メソッド呼び出し後(スクロール完了)の状態>
この辺の処理も HistoryLayer クラスの scrollUp メソッドのスクリプトと見比べてみると、 似てるのがわかると思うよ。 | |
確かにやってることは似てるね。 | |
それじゃ今度は diff が 0 より小さい時の処理を見てこっか。 | |
履歴メッセージを前の方にスクロールする時だね。 | |
ん。スクリプトを見てもらえばわかると思うけど、 履歴メッセージを先の方にスクロールする時とやり方はほぼおんなじだね。 | |
今度は HistoryLayer クラスの scrollDown メソッドに似てるってことだよね? | |
そ。これも1行スクロールするか複数行スクロールするかの違いだね。 | |
あ、でもこっちは最初に “diff = -diff;” って書いてあるけど? | |
あー、これね。 この後 copyRect メソッドの引数を指定したり for ループのループ条件を指定する時に、 diff がマイナスになってるとちょっとわかりにくくなりそうだから、 diff の値をプラスに変えてるの。 |
|
それってどーゆーコト? | |
例えば、4行前にスクロールする場合は diff が -4 になってるから、 “diff = -diff;” を実行して diff の値を 4 にするってこと。 | |
diff が -4 の時に “diff = -diff;” を実行したら 4 になるの? | |
“diff = -diff;” を実行すると、 diff の値のプラスマイナスが逆になるの。 | |
ふぅん、そーなんだ。 | |
要するに、今まで diff は “何行先にスクロールするか” を表してたんだけど、ここから(“diff = -diff;” を実行した後)は “何行前にスクロールするか” を表すことになるって考えてもらえば OK だよ。 | |
そっか。りょーかい。 | |
さて、こっからは履歴メッセージを先にスクロールする時と基本的にやり方はおんなじだから、 あとは説明よろしくね。 | |
えっ、ここからわたしが説明するの? | |
scrollDown メソッドの時もほとんど説明してくれたし、大丈夫でしょ? | |
う〜ん…まぁ多分大丈夫だと思うけどねぇ。 | |
ん、じゃよろしく。 | |
えーっと、最初の clearActionHighLights メソッドは前に何回も出てきてるからいーよね? | |
うん。じゃ次いこっか。 あ、こっちも横書き表示の時だけでいいよ。 |
|
わかった。 横書き表示は verticalView が false だから、else ブロックの方だね。 |
|
ん。あ、あとメッセージ履歴画面に表示できるメッセージは10行(dispLines は 10)になってて、 4行前にスクロールする(diff が 4 になってる)ってことにしといて。 | |
おっけー。 えっと、scrollDown メソッドの時は copyRect メソッドのコピー元の四角形は一番下の行以外の部分だったから、 4行前にスクロールするんだったら… |
<4行前の方にスクロールする場合の copyRect メソッドでのコピー元領域>
こんなふうに、下から4行分以外の部分がコピー元になるよね。 それから、scrollDown メソッドの時は copyRect メソッドのコピー先の四角形は一番上の行以外の部分だったから、 4行前にスクロールする時のコピー先は… |
<4行前の方にスクロールする場合の copyRect メソッドでのコピー先領域>
こんな感じで、上から4行分以外の部分がコピー先になるね。 | |
うんうん。 | |
だから、copyRect メソッドを呼び出すと… |
こうなるよね。 | |
そーだね。 | |
次は clearBack メソッドで、 こんなふうに上から4行分の履歴メッセージを消すんだね。 |
ちなみに、ここの for ループの中の clearBack メソッドは、 i が 0, 1, 2, 3 の時に呼び出されるから、上から4行分が消えるんだよね。 | |
そうそう。 | |
それから、drawLine メソッドを呼び出す前に
dispStart に line の値を代入して、
clearBack メソッドで履歴メッセージを消したとこに、
ここの for ループの中の
drawLine メソッドで0〜3行目の履歴メッセージを書き込むんだね。 だから、最終的に… |
<drawLine メソッド呼び出し後(スクロール完了)の状態>
こうなって、スクロール完了だよっ。 | |
うん、バッチリだね。 | |
スクロール処理ってパターンがあるから結構わかりやすいよね。 | |
だね。 後は、スクロール処理でメッセージ履歴画面の内容が変わったから、 最後に updateButtonState メソッドを呼び出して終了だね。 |
|
そーいえば、updateButtonState メソッドってなんにもやってなかったと思うんだけど、呼び出す意味あるの? | |
※§10.9 参照。 | |
今は何もやってないけど、後でちゃんと使うから。 | |
あ、そーなんだ。 | |
それじゃ、今回はここまでね。 次回で基本編は終わりだよ。 |
|
基本編ってタイトルのわりにはすごい長く続いてるよね… | |
う〜ん…ホントはもっと簡単にまとめるつもりだったんだけど、
うまくまとめられなくって長くなっちゃったんだよね… ま、とりあえず次回で基本編は最後ってことで。 それじゃ、また次回ね! |