FileMaker でよく使う小ネタや小技があります。処理待ちの僅かな間に表示するローディング画面というかパーツをgifアニメ付けて用意することもその一つ。
時間がかかる処理を行う時はプログレスバーを出したくなります。その方法は過去いろんな達人が編み出して紹介されていますね。今回のネタはプログレスバーを出すほどでもない僅かな処理時間を埋めるパーツの表示です。こういうローディングの画像を含めたいと思います。
wait…
処理待ち時間にフィードバック
作成中のメディア管理での対策
FileMakerでメディア管理データベースを作って育てています。実際のファイル MediaDB_R11.fmp12 についての話題のひとつでもあります。
ファイルが育ちレコードや分類が増えるに従って、小さな処理待ちの時間が気に触り始めました。例えばフィルタ操作で項目名をクリックしてから検索結果が表示されるまでに待たされる時間です。僅かですが、僅かであるからこそストレスになります。
処理待ち時間に何かを表示する
このストレスを軽減する対策として有効なのは、処理を開始する前に何らかのオブジェクトを表示させて処理待ちが発生していることを示すことです。理想はカーソルの形を変えたりカーソル近くに小さなオブジェクトを表示することですが、FileMaker ではどちらもできません。固定の場所にオブジェクトを置くことで妥協します。
処理が遅いストレスの対策として、処理前にオブジェクトを表示させることに意味あるのか。あります。
Apple Human Interface Guidelines に基づいたフィードバック
昔Macがコンピュータに革命を起こした頃、「Apple Human Interface Guidelines」という書籍がありました。今においても重要な指摘の宝庫で、開発者のみならずデザイナーや使い勝手研究者のバイブルと言って良い書物です。
開発者ならお経代わりに毎日音読せよと思うほどお気に入りかつ大事な指摘がこの本にありまして、それは「ユーザーの操作に対するフィードバックを瞬時に返せ」という教えです。
何か操作をしようとユーザーがクリックしました。その直後、何より最優先に、コンピュータの性能を全部傾けて良いから「クリックを受け付けたよ!これから処理するからちょっと待ってね」というフィードバックを返せ」というようなことが書かれていました。
瞬時にフィードバックを返すことを怠らなければ、ユーザーは処理に時間がかかっても待てるんです。逆に、フィードバックが何もなかったり遅れたりすれば「今の操作が伝わっていないかも」と思って何度もカチカチしたり、ストレスを感じたりします。操作に対するフィードバックはすべてに優先されるべきである。とのことです。
このことはゲームで考えれば当然のことだとわかりますね。Aボタン押して1秒後にマリオがジャンプするとか、「まほう」を選んでAボタン押したのに画面は無反応で1秒後にようやく「ホイミ」と出てきたら人はぶち切れます。
この研究と洞察をコンピュータ黎明期の最初にぶち上げた世界に誇るAppleのUI研究部署ですが、後にスティーブ・ジョブズによって解体されました。AppleのUIやデザインの劣化はUI研究部署の解体から始まり、世界に悪影響をもたらしました。
wait…
自作のメディア管理DBのフィルタ操作で言えば、クリックを受け付けたら検索の処理を始める前に「クリックを承りました。僅かに処理時間がかかりますがお待ちください」のフィードバックを返すことにしたわけです。
カーソル位置の近くにオブジェクトを配置する機能がFileMakerにないので、仕方なく固定の位置に置きます。
何かしら操作のクリックを行えばまず最初にこれを表示します。その後処理を開始し、終わったら消します。動いているところはこんなふうです。このオブジェクトのデザインや出し方そのものが気に入っているわけじゃないので、今後変更したりいろいろあるとは思います。
たったこれだけのことで精神衛生上とても良い効果があると改めて確信しました。何をさておいてもフィードバックを優先させろという昔のAppleの研究者たちの考えは素晴らしいですね。おいこら今のApple、聞いてんのか。
Loading.gif を表示する
Loading.gif
このくるくる回る gifアニメがあるとないでは印象が大違いです。あったほうがいいです。
最初は何も知らず gifアニメをレイアウト上にコピペしたんですが、FileMaker で gif アニメは動いてくれません。残念。それで諦めていました。でもWebビューアなら表示できますよね。
Webビューアに表示する方法
方法は、base64化した loading.gif を含んだHTMLを webビューア設定に書くだけです。
完成形のHTMLを貼り付けるだけです。が、ここは少しカスタムできる余地を残したいので、MediaDB では設定テーブルに二つのフィールドを作成しました。
base64
Loading.gif を埋め込むオブジェクトフィールド「loading_gif」と、base64化の計算式を含むテキストフィールド「loading64」です。どちらもグローバルフィールドで、loading.gifを入れ替え可能にしたということですね。
base64化の計算式は関数 Base64EncodeRFC ( “” ; loading_gif ) を使っています(改行を追加しない)
HTML
Webビューアを配置し、HTMLを次のように設定しました。
"data:text/html," &
"<html>
<head>
<style type=\"text/css\">
* {border:0; padding: 0; margin: 0 ;overflow: hidden;}
body {background:#FFF;}
div { display: flex; justify-content: center; align-items: center; height:100%; }
img { width: 100% ; height: auto; max-width:32px; max-height:32px;}
</style>
</head>
<body>
<div>
<img src=\"data:image/gif;base64," & 設定::loading64 & "\" >
</div>
</body>
</html>"
少しだけ解説すると、読み込んだ gif ファイルのサイズを max値に置き、それ以下では100%サイズにしました。
div は display: flex で、 img を中央表示します。
background color は何色に設定してもいいんですが、HTML解析のほんの一瞬、どうしてもWebビューアが白くなります。
これが避けられないので潔く白とし、背景オブジェクトも白くして無理矢理合わせました。
呼び出すスクリプト
loading.gif を含めたオブジェクトをグループ化して「隠す」で表示をコントロールします。
「wait開始」「wait終了」スクリプトをあえて作成し、どこからでも呼び出せていつでも修正できるように準備しました。
最初は表示オンオフを司るグローバル変数を使っていました。グローバル変数 $$wait が 1 なら表示、そうでなければ隠します。この場合、必ず「ウインドウ内容の再表示」とセットで使わなければなりません。
再表示のスクリプトステップを挟み込みたくない場合はフィールドを使います。「隠す」判定の発動は、変数だと再読み込みが必要ですがフィールド値だと不要なんですよ。知ってた?
そこで不本意ながらまたまたフィールド「wait」を一個追加しました。このフィールドに「1」をいれるか消すかだけの簡単な工程が「wait開始」「終了」スクリプトの中身です。
「wait開始」にはもう一つ小さなステップがあって、[ スクリプト一時停止:.2 ]と、わざわざ時間を引き延ばしています。そうすることで loading.gif がちゃんと動き始めます。
処理待ちストレスを軽減するために処理時間を引き延ばすこの思想の根幹こそが Human Interface Guidelines の神髄です。
スクリプトのあり方を考察
wait開始・終了のスクリプトを、少し待たせる作業を伴う他のスクリプトすべてにセットすることを目指して、実際にそれをやりはじめてハタと気付いたことがありました。我ながらスクリプトの作り方が雑すぎて駄目なんです。
スクリプトの作りが雑すぎるというのは、本来の処理と表層的な処理をごちゃ混ぜに書いてしまっているパターンが多すぎるということです。スクリプト内で別のスクリプトを呼び出すことも多く、利用するシチュエーションが定まっていないものもあります。つまりそういうスクリプトに対して「wait」をどこにどう付ければ良いのかわからないという混乱が生じます。
つまりですね、例えばscriptAがあります。scriptBがあります。scriptBの中にはscriptAを呼び出すスクリプトが含まれます。
レイアウトのボタンにはscriptAを発動させるものも、scriptBを発動させるものもあります。
さて、AにもBにも「wait開始」「wait終了」があればどうでしょう。Bの中で開始・終了が複数起きますね。ダメダメじゃん。と、こうなります。「wait開始」「wait終了」を書くべきスクリプトが決められません。そういうときのために、wait発動を if の条件分岐で分けますか?
実はこれまではそのようにしていました。wait に限らず、似たシチュエーションはよくあります。結果、ますますスクリプトが無駄な記述であふれますね。
これは根本的にスクリプトの書き方が悪いんだと、遅すぎますがようやく気がつきました。次のような課題を今後の改良の糧にしていきたいと思います。
本来の処理に特化したスクリプトを作る
シチュエーション別に、処理スクリプトを呼び出すスクリプトを作る
処理そのものと、その処理を発動することを分離して二段構えで作るという意味です。全部例外なくそうしろという強迫神経症的な思いはありませんが、このような作りを目指すべきだと思いました。
ということで、loading.gif の小さな画面を表示する簡単な内容ですが、デジタル部思想部長の主義主張があふれたエッセイコラムのような投稿でございました。
本日の内容は、FileMakerで作るメディア管理データベース、そのR11 をベースとしています。
ところで、Human Interface Guidelines。私は復刻版を所持しているんですが、今でも売ってるのかなと探してみたところ、どえらいことに💦 いや、この本は永遠に再販続けないといけないですね。
Human Interface Guidelines:The Apple Desktop Interface (日本語版)単行本(ソフトカバー) 新紀元社 (2004/7/1)
Amazon (広告)