出典:http://compasstech.com.au/TNS_Authoring/Scripting/script_tut19.html
レッスン19「Lua Nspiredドキュメントの作成ガイドライン(その1)」
複数のプラットフォームで動作するドキュメント(Create Once Play Everywhere)
LuaとTI-Nspireとを使って独自のドキュメントを作成する場合を考えてみましょう。
ドキュメントを作成する場合は、仕事として作成する場合も、自分の生徒のために作成する場合も、ユーザーが快適に使用できることが重要です。究極の目的は、効果的な学習体験をもたらすことにあるわけであり、ユーザーとドキュメントとの間に設計上の問題や使いやすさに関する問題が存在していては、その目的が達成されません。
実行環境にかかわらず効果的に機能できるドキュメントを作成するにはどうすればよいのか。本稿で述べるガイドラインおよび以下のチュートリアルでは、そのための重要な検討事項について示します。
ここでは2つの点について述べます。1つは、TI-Nspireの各種プラットフォームでのドキュメントの表示についてです。これは、レッスン19(設計と表示について)で述べます。もう1つは、ユーザビリティーについてです。これはレッスンレッスン20で述べます。説明に従ってドキュメントを作成すれば、PlayerやPCと同じようにハンドヘルドでも(どのような環境でも)簡単かつ効果的に使用できるドキュメントが作成できます。
- 表示について:環境にかかわらず見栄えを良くする
Lua Nspireドキュメントを作成する場合にまず考えなければならないことは、ハンドヘルドでもPCでも、あるいはPlayer、PublishView、その他のプラットフォームでも、ドキュメントの縮尺が正しく変化することであり、ユーザーが快適に使用できることです。TI-Nspire専用の機能を用いて作成したドキュメントにLuaドキュメントを併用する利点の1つは、正しくスクリプトを作成しさえすれば、そうしたドキュメントがどのような環境でもうまく表示できることにあります。この点についていえば、Nspireの組込アプリケーション、特にGraphsとGeometryは、多大な努力が払われているにもかかわらずお粗末です。
“Math Nspired document for Arcs and Sectors”を見れば、そのことがよくわかります。最初の2つの画像は、オリジナル・ファイルから引用したページです。ハンドヘルド・ビューでは見事に表示されていますが、コンピューター・ビューはひどいものです。その下にあるのが、同じページのLuaバージョンです(ありがとう、ジョーン・ハナ(訳註:誰?)。同じようにハンドヘルド・ビューとコンピューター・ビューとを並べて表示しました。Luaドキュメントのもう1つの利点は、円の円周を移動するポイントが矢印キーだけで操作できることにあります。ハンドヘルド上でポイントをつかんで動かすときのように、画面上で必死にポインターを動かす必要がありません。コンピューター・ビューでマウスを使うのと同じように効率的に操作ができるのです。これについてはレッスン20で詳しく述べます。
寸法および位置の基準はすべて、画面サイズに対して相対的な値にすることが絶対原則です。位置、寸法のどちらについても、あるいはその始点についても、絶対値を使ってはなりません。そんなことをしてしまえば、使用環境によって表示が崩れかねないからです。
- 1.1 絶対値ではなく相対値で指定する
これについては、幅および高さを示す各変数を下のように定義すればいとも簡単に達成できます。
W = platform.window:width()
H = platform.window:height()
位置を示す変数は、上の変数で表現します。たとえばオブジェクトの初期位置をW/2、H/2と指定すれば、そのオブジェクトがページの中央に配置できます。寸法についても同様です(下の1.3、1.4を参照)。
- 1.2 on.resize()函数
前述したグローバル変数は、ページ寸法が変化したときに必ず呼び出されるよう、on.resize函数の中で定義するのが最も効果的です。こうしたルーチンは、ページが作成されたときにも呼び出されるので、変数およびオブジェクトの初期値を定義する場所に適しています。
on.resize函数は、たとえばon.escapeKey()やon.mouseDownの実行時に簡単に呼び出せます。
- 1.3 オブジェクトの寸法は相対値で指定する
円や正方形のような対称形のオブジェクトの寸法は、W(platform.window:width)またはH(platform.window:height)のどちらかを基準とする相対値として指定するのが最善です。したがってたとえば、円または正方形の幅および高さの初期値はどちらも、W/30のように相対値として指定することができます。
- 1.4 フォント・サイズは相対値で指定する
大きな画面になるほど大きなテキストが表示されるよう、フォント・サイズをページ幅などの値にリンクすることができます。ハンドヘルド・ウィンドウの標準的な幅を318ピクセルとすれば、変数を下のように定義しても良いでしょう。
fontSize = W/32
こうすれば、フォント・サイズはハンドヘルド上では10に近い値になります。この値は、setFontコマンドを使った場合には自動的にwhole numberに丸められますが、math.floor函数を使えば必ずinteger値が返ってきます(0.5を加算すれば必ず元の値に最も近い値になります)。フォント・サイズは最小値が6、最大値が255です。フォント・サイズに制限を設ける手段としては以下のように定義するのが良いでしょう。
fontSize = math.floor(W/32 + 0.5)
fontSize = fontSize >= 6 and fontSize or 6 --fontSizeが6以上ならfontSizeを返し、それ以外なら6を返す
fontSize = fontSize <= 255 and fontSize or 255 --fontSizeが255以下ならfontSizeを返し、それ以外なら255を返す
(訳註:上の3行はfontSize = math.max(math.min(fontSize,255),6)のようにmedian函数を使って1行で指定しても多分同じ)
注:アンディー・ケンプの指摘によれば、PC上で扱えるフォント・サイズは6~255ポイントであるが、ハンドヘルドでは7、9、10、11、12、24に制限されています。上記のように制限を設けてもハンドヘルドでは問題は起きません(6ポイントは7ポイントとして表示されるし、24ポイントを超えてもそれ以上大きくならない)。しかし、ハンドヘルドと他のプラットフォームとでページ表示の異なることがあります。
可能な限り一貫性を持たせたい場合は、制限はきつくなりますが以下のようにするのが安全でしょう。
fontSize = math.floor(W/32 + 0.5)
fontSize = fontSize >= 7 and fontSize or 7
fontSize = fontSize <= 24 and fontSize or 24
- 1.5 インテンディド・ページ・サイズ ―― もうひとつの方法
アルフレッド・ロドリゲスに感謝します
前項で述べた方法は、さまざまなページ・サイズ、さまざまなプラットフォームでドキュメントがうまく拡大、縮小されるようにするための最も簡単な方法でしょう。しかし別の方法もあります。インテンディド・ページ・サイズを最初に定義しておいて、そのサイズを基準に拡大、縮小を行うという方法です。
まず、インテンディド・ページ・サイズを定義するところから始めます。ハンドヘルドという、限られたスペースでうまく表示できるようにするため、ハンドヘルド・ウィンドウのサイズを選択し、それを基準にして拡大します。
local iW = 318
local iH = 212
最初に縮尺比も定義します。
local sf = 1
標準的なPaint函数を面白く変化させたものを次に示します。処理の内容をよく見て、その目的が理解できるかどうか確かめてください。
function on.paint(gc)
-- Enable handlers
on.paint = onPaint
on.resize = onResize
-- Call initial onResize
onResize(platform.window:width(), platform.window:height())
-- Call initial onPaint
onPaint(gc)
end
Resize函数に含めておかなければならないのは、事前に定義しておく必要のあるその他の初期変数またはオブジェクトだけではありません。platform windowの寸法を基にしてScale Factorを定義することもResize函数に含めておかなければなりません(以下に示す見事な方法を提案してくれたネビル・ホプリーに感謝します)。この時点でフォントも定義しておきましょう。こうすれば、単純な拡大・縮小函数がスクリプト全体に適用されます。
function onResize(w, h)
sf = math.min(w/iW, h/iH)
fontSize = 10*sf
fontSize = fontSize >= 6 and fontSize or 6
fontSize = fontSize <= 255 and fontSize or 255
end
function s(a)
return math.floor(a*sf + 0.5)
end
Paint函数によって、適切に縮尺の設定されたオブジェクトが表示されます。左の図がハンドヘルド・ビュー、右の図がコンピューター・ビューです。フォントも見事に拡大・縮小されています。
function onPaint(gc) local x = s(iW/4) local y = s(iH/4) local w = s(iW/2) local h = s(iH/2)
-- Draw background gc:setColorRGB(200, 200, 250) gc:fillRect(x, y, w, h)
-- Draw lines gc:setColorRGB(150, 150, 250) gc:drawRect(x,y, w, h) gc:drawLine(x,y, x+w, y+h) gc:drawLine(x,y+h, x+w, y)
-- Draw Messages gc:setColorRGB(150, 30, 30) gc:setFont("sansserif", "b", fontSize) local str = "We put technology in your hands" local sw = gc:getStringWidth(str) gc:drawString(str, s(iW/2)- sw/2, s(iH*0.9), "bottom") end |
- 位置もオブジェクトの寸法もすべてが、拡大・縮小函数によって処理されていること、インテンディド・ウィンドウ・サイズで表現されていることを確認してください。
確かに最初の方法よりは面倒です。しかし明らかな利点が1つあります。それは、1個の変数が変化したときにウィンドウ全体のスケールを変更したいような場合です。後者の方法は、Scale factor変数1つを変えるだけで、それ以外がすべて追従して変化しますすので簡単です。しかし前者の方法は、同じことをしようとしたら相当な変更が必要となるでしょう。
レッスン20では、快適に使用できるようにするためのユーザビリティーについて検討しながら、有益なガイドラインと原則について引き続き説明します。ハンドヘルドの使用を中心に述べますが、他のプラットフォームにも適用できる内容でです。
-----------------------------------------------------------------
(訳註)今回の実行結果。スクリプトはオリジナルのまま。