![]() |
今回は 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 参照。 | |
![]() |
今は何もやってないけど、後でちゃんと使うから。 |
![]() |
あ、そーなんだ。 |
![]() |
それじゃ、今回はここまでね。 次回で基本編は終わりだよ。 |
![]() |
基本編ってタイトルのわりにはすごい長く続いてるよね… |
![]() |
う〜ん…ホントはもっと簡単にまとめるつもりだったんだけど、
うまくまとめられなくって長くなっちゃったんだよね… ま、とりあえず次回で基本編は最後ってことで。 それじゃ、また次回ね! |