FileMakerでファイルを作るときにいつも必ず使う小ネタ・小技があります。今回はウインドウサイズの話題です。小ネタでは済まんかった。
最適化すること
昔Macに「ウインドウ最適化ボタン」というスマートかつエレガントなボタンがありました。
最適化ボタンは緑ボタンに引き継がれましたが、その後「最大化」に落ちぶれ、やがてフルスクリーン化という酷い最後を遂げました。
今でも最適化機能はかろうじて残っていて、タイトルバーのダブルクリックがそれです。アプリによりますが下品に最大化されてしまったりエレガントに最適化されたりします。
FileMakerのスクリプトステップに同じ機能あります。「ウインドウの調整」の「収まるようにサイズ変更」がそれです。
レイアウトモードで作成したサイズがデフォルトとして「収まるサイズ」になります。フォーム表示の場合は幅と高さ、リストや表の場合は幅が合致して高さがディスプレイの高さになります。
ウインドウを最適化させたいとき、基本、このスクリプトステップ1行で事足ります。
とはいえ、トリガ(OnLayoutEnter)に仕込んだり、「レイアウト切り替え」を行うスクリプトの中に混ぜ込んだりもしたいので、スクリプトを作っておくのがよろしいですね。そして最適化の1行だけでは不足を感じることもあります。
ウインドウサイズ関連のスクリプトステップにはもうひとつ「ウインドウの移動/サイズ変更」があります。
こちらはウインドウの位置やサイズを計算で調整できます。
ウインドウを最適化させるスクリプトを作る際、これらステップを使ってちょいと工夫を凝らします。
FileMaker で最適化すること
スクリプトを使ってウインドウサイズを最適化させることに凝り出すと、だんだん深みにはまっていきますが順を追っていきましょう。
LEVEL 1: さくっと最適化
「収まるようにサイズ変更」を使うだけですが、リストや表の表示ではわずかに手間をかけます。
LEVEL 2: こだわりのリスト表示
リスト表示の高さをより詳細に制限します。
LEVEL 3: トグルボタン
最適化と手動サイズをトグルで行き来することについて。
LEVEL 4: 記憶と再現
レイアウトを細かく記録し管理します。
ではいきます。
LEVEL 1: さくっと最適化
最適化スクリプトを作ることから始まります。
収まるようにサイズ変更
スクリプトの中は超簡単。「ウインドウの調整」で「収まるようにサイズ変更」を選びます。
簡単ですね。
スクリプトステップ「ウインドウの調整 – 収まるようにサイズ変更」は、レイアウトの表示方法によって最適化の挙動が異なります。
フォーム形式の場合はレイアウト編集で定めたサイズ、リスト形式や表形式では縦が画面いっぱいになります。
リストや表の縦サイズは、画面の小さなノートタイプでは気になりませんが、大きなデスクトップでは縦が長すぎると感じることがあるので、縦サイズを制限したくなります。
ウインドウの移動/サイズ変更
そこで、一度「収まるようにサイズ変更」してから、続けてウインドウを調整します。ウインドウの移動/サイズ変更です。
スクリプトでは表示方法によって分岐させます。
ウインドウの調整[ 収まるようにサイズ変更 ] if [ Get (レイアウト表示状態) = 0 ] #フォーム表示の場合 else if [ Get (レイアウト表示状態) = 1 ] #リスト表示の場合 else if [ Get (レイアウト表示状態) = 2 ] #表の場合 end if
ここで注意すべきポイントは表示形式で条件分岐してるのに関数が「表示状態」なところです。→ FileMaker ウインドウに関する忘れがちな用語のまとめ – 表示方法・表示形式・表示状態
高さを制限
個人的な感覚にすぎませんが、27インチ以上のディスプレイで縦いっぱいにリストや表が広がるのが鬱陶しいんです。
リストや表では高さ1100pxくらいに収まってくれると見やすいなと思ったりしますので、サイズと位置の高さを指定してみます。
if ( Get ( ウインドウ高さ ) > 1100 ) ウインドウの移動/サイズ変更 [現在のウインドウ ; 1100 ]
こんな感じで制限掛けてます。これを、上記の条件のリストと表にあてがいます。・・・高さいっぱいに広がることに抵抗ある人も少ないと思いますが。
さくっと最適化スクリプトはこんな感じになりました。
維持するとき
直前に表示していたレイアウトの高さを維持したいときもあるかもしれません。そんなときは[ウインドウの移動 サイズ変更]で高さのところに Get(ウインドウ高さ) と入れておけば良いですね。
位置を再現
リスト表示で必須とも言える「最適化後の位置」について書かずにおれません。
リスト表示を「収まるサイズ」調整すると、ウインドウの位置がディスプレイ最上部に飛んでいきます。これが地味に嫌いなんです。その場で収まるサイズになってほしい。そのためには、事前に準備が必要です。
最初の最適化を実行する前に、現状のウインドウ位置を記憶しておきます。
Get ( ウインドウ上位置 ) と Get ( ウインドウ左位置 ) をあらかじめ変数に保存してからウインドウ調整を開始します。例えば $top に上位置、$left に左位置をセットします。
「ウインドウの移動/サイズ変更」で、「上端からの距離」に $top、「左端からの距離」に $left と入れ、最適化ですっ飛んでいったウインドウ位置を整えます。
位置を合わせたので、縦が画面からはみ出してしまうかもしれません。対処が必要ですね。「高さ」を再考しましょう。
デスクトップの高さから上位置を引いた残りが表示できる領域ですので、さっき設定した高さがそれより大きいかどうか比較して大きければ領域に合わせます。
スクリプトの全体像はこうなりました。
細かい話をし始めるといろいろありますが「位置の記憶」と「収まるように」調整、そして微調整と、このあたりで十分だったりします。これらに満足できないときのみ、自分で最適化スクリプトを作り上げましょう。
ボタン
最適化スクリプトをどのように利用するかというと、ボタンに仕込むとエレガントな「ウインドウ最適化ボタン」になります。
このボタンに細工を施すことで、ウインドウサイズを好きな値に強制させることもできます。ボタンにスクリプト引数をセットします。目的のウインドウ位置とサイズをマイルールに基づいて、例えば top, left, width, height の順に「”8,8,1280,780″」とか書いておくわけです。
割り当てるマイ最適化スクリプトには、ウインドウ調整[収まるサイズ] を書いておきますが、その前に if を入れて、もしスクリプト引数があれば(not isEmpty ( Get ( スクリプト引数 ) ) )引数でウインドウを指定するんですね。例だと「 カンマを改行に置換して、1行目から $top, $left, $width, $height と変数にして「ウインドウの移動 サイズ変更」のそれぞれの欄で指定します。
という余計な一例でした。
LEVEL 2: こだわりのリスト表示
引き続き「最適化」スクリプトです。
LEVEL 1 でそれなりのスクリプトができました。しかしリスト表示にはリスト表示なりの美しさの追求というものがあります。追求しましょう。
高さ再考
高さについて先に述べました。ウインドウいっぱいにまで縦が広がるのを好ましくなく思っているので高さを制限しましたと。
レコード数
リスト表示にもいろいろあって、レコードがたくさんある想定と、すごく少ないレコードの場合があります。考え方が異なります。
レコードが沢山ある場合のリスト表示は「美しい表形式」みたいな感覚です。この場合、大きなディスプレイでは高さを制限したいと考えました。
レコードが少ないってどういうことかというと、ファイルのランチャーだとか、値一覧で使用するような少ないレコードの一覧、ちょっとしたカタログみたいな、あるいは常にフィルタ前提で表示レコード数が10個とかそんなレイアウトの想定です。
レコードが少ない想定のリスト表示
ここでは、レコードが少ない、あるいは、絞り込み結果のレコードが少ないことが想定されるリスト表示について考えます。
例をあげてみようかしら。
全表示だとそれなりに表っぽくて良いんですが、このファイルは通常フィルタして絞り込んで使うようなタイプなので、下の空白が気になります。
もうひとつもっとわかりやすい例、FMランチャー&修復ユーティリティ(笑)なんですが、レコードは極端に少ないです。
キャプションで書いたとおりなんですが、リスト表示でファイルメーカーの用意した最適化を行うと真ん中の画像のように縦がびろーんと伸びてしまいます。
実はFinderというかMacの最適化(タイトルバーのダブルクリック)では理想の形になります。
理想の形に整えたい。
レコード数に応じたウインドウサイズ調整
レコード数とウインドウ高さを連動させたいんです。
フォームのところでGet(ウインドウ幅)とGet(ウインドウ高さ)を得て再現しましたが、リスト表示ではもうちょい複雑になります。
パーツの高さを得る
まず前段階としてレイアウト内のパーツの高さを知ります。
ヘッダとフッタ関連の使用しているパーツ、ボディの縦サイズをあらかじめ(グローバル変数またはグローバルなフィールドまたはスクリプト引数などに)登録しておきます。
ウインドウ内容高さは、( ボディの高さ×レコード数 ) + 使用パーツの高さの合計 となります。計算式で最適な高さを得ることが出来ますね。
LEVEL 1 で設定したウインドウ高さをこのように変えてみました。
ボディの高さ、パーツ高さ計は、レイアウトごとに異なりますね。どうしますか。対処の方法はいろいろあります。
例えば最適化ボタンのスクリプト変数に仕込みます。「60 ¶ 140 」みたいに。高さ計算の最初にスクリプト引数をゲットして改行ごとGetValue して、ボディとパーツに当てはめます。
私はこだわりのあまり「レイアウト管理」テーブルを作り、さまざまな数値を設定してそのテーブルからレイアウト名に合わせて引っ張ってきたりしていました。レイアウト管理は懲りすぎて凄い発展し、本末転倒しました。ある日我に返って「わしあほとちゃうか」と全部破棄、結局 LEVEL 1 程度のものに落ち着きました。
厳密にやり始めるとキリがないですが、ざっくり、ボディ×対象レコード に、ボディ外のパーツの高さを何となく余裕見て足せば良いという話でした。
LEVEL 3: 最適化トグルボタン
最適化のスクリプトもできてボタンに仕込んだりするわけですが、真のエレガントな最適化ボタンであるなら、最適化と手動サイズのトグルボタンになるべきであるという話です。
手動でウインドウサイズを変更することもありますね。その状態で最適化ボタンをクリックすれば最適化サイズになります。もう一度同じボタンをクリックしたら、先ほど作業していたサイズに戻ってほしい、そういうことです。トグルで最適化と手動サイズを行き来したい。それを実現します。
「最適化トグル」スクリプトについてです。
先に書いておくと「最適化トグル」の他に、「最適化」と対を成す「元に戻す」スクリプト、ウインドウを手動でサイズ変更したときに発動させる「サイズチェンジトリガ」スクリプトを作ります。
元に戻す
「ウインドウを調整」ステップには「収まるようにサイズ変更」の他に「元に戻す」があります。元々エレガントな機能が用意されていますよ。「元に戻す」スクリプトを作りましょう。
これで十分じゃん。その通りで、このステップとオプションを使えば簡単に実現します。「元に戻す」のサイズをこだわりの数値にしたいときは後ほど独自に「元に戻す」スクリプトを充実させてください。ここでは「元に戻す」で十分であるということで話を進めます。
最適化と元に戻すを行き来させるにはボタンに仕込んで並べれば取りあえず実現します。
しかしボタンを並べただけでは不細工ですね。「一つのトグルボタンにしたい」ことでハードルが少し上がります。
一つのボタンで最適化と戻すを繰り返したいとき、if で処理を分けます。if の条件ネタが必要で、それにはグローバル変数を使うのが良いでしょう。
グローバル変数 $$最適化 で判断
「$$最適化」というめっちゃわかりやすい名前のグローバル変数を想定してみましょう。最適化されたら 1、そうでなければ 0 または “”(空)にするということにしておきます。
クリックして収まるサイズにしました。直後、 $$最適化 = 1 とセットします。元に戻すを実行しました。直後、$$最適化=”” と空にします。ボタンのスクリプトをどう書きますか?簡単ですね。
「もし $$最適化 = 1 なら元に戻すを実行して$$最適化を空に、そうでなければ最適化を実行して$$最適化=1にセット」このようなスクリプトを書きます。
最適化と元に戻すがトグルで交互に発動するボタンのスクリプトが出来ました。
これだけでいいでしょうか? いいえ足りません。例えば手動でウインドウサイズを変更することだってあります。
ウインドウの変更に対応
スクリプトトリガ OnLayoutSizeChange を使います。これはサイズが変更されると発動します。スクリプトを作って割り当てましょう。
最適化されたウインドウだろうがされていないウインドウだろうが、ウインドウサイズを変更した場合それは最適化状態ではなくなります。ですので、スクリプトで $$最適化 = “” を指定します。これでOKですね? いいえ、OKじゃありません。
OnLayoutSizeChange はウインドウサイズが変更されれば必ず発動します。そうです。最適化ボタンクリックで最適なサイズに変更しても発動してしまいます。これはマズいですね。「最適化」が発動されたときは OnLayoutSizeChange の $$最適化 = “” を発動させないようにしておきたいです。命令を無視してすっ飛ばすことを「バイパス」と言いますね。$$バイパス というグローバル変数を想定してみました。
OnLayoutSizeChange のスクリプトに「もし $$バイパス = 1 なら、$$バイパスを空にしてスクリプト終了」を付け加えます。
一方、最適化ボタンのスクリプトでは、最適化実行の前に $$バイパス = 1 と変数を指定します。[元に戻す]の前には不要ですよ。
最適化トグルまとめ
登場人物は四名です。
[最適化トグル]
[サイズチェンジ]
[最適化]
[元に戻す]
グローバル変数は次の二名です。
$$最適化
$$バイパス
流れをまとめましょう。
- [最適化トグル] … クリックしたとき
- 現在 $$最適化 = 1 の場合
- [元に戻す]を実行。$$最適化 = “” 空にする
- 現在、$$最適化 = “” の場合
- $$バイパス = 1をセット する
- [最適化]を実行し、$$最適化 = 1 にセットする
- 現在 $$最適化 = 1 の場合
- [サイズチェンジ] … ウインドウサイズ変更時
- $$バイパス = 1 の場合
- $$バイパス = “” 空にしてスクリプト終了
- $$バイパス = “” の場合
- $$最適化 = “” 空にする
- $$バイパス = 1 の場合
これでいかがでしょうか。
LEVEL 4: 記憶と再現
この章は実例の画像添付もなく理屈っぽくて難解と感じられるかもしれません。無理に読まなくてもいいです。掘り下げたい人のみ、お進みください。ページの最後に、ウインドウサイズ早わかりファイルのダウンロードがありますのでそれだけでもOK。
本ポスト、上の方では少し調整を加えた最適化やこだわりのリスト表示について書きました。
次に、トグルについて書きました。最適化の内容そのものについては掘り下げずデフォルト挙動です。
トグルを実現しつつ、「最適化」と「元に戻す」をさらに掘り下げ、自由自在に数値を設定するマイ最適化、マイ元に戻すみたいなのを実現したいと思うようになってくるかもしれません。
そしてデータベースが育っていく中、ウインドウが複数開くとか、いろいろシチュエーションを想定すると $$最適化 のグローバル変数が力不足と判ってきます。
単に $$最適化 だけではだめで、個別にウインドウ名を記したいという考えに至るでしょう。特定ウインドウ名が最適化されているかどうか、特定ウインドウの位置とサイズ、そういう記録が必要と思えてきます。そして記録は再現するために使います。
ウインドウサイズ調整、最適化というのは何と奥深い話でありましょうか。
記憶・記録するタイミング
ウインドウ毎あるいはレイアウト毎に調整
レイアウトごとあるいはウインドウごとにそれぞれ自動最適化や手動保持をしたいというお話です。記憶させ、再現します。デフォルトサイズを手動で指定したり、時にはバイパスしたり、ウインドウ情報の記録とそれをゲットして利用する仕組みへと発展します。
ウインドウサイズが変更されたとき
最適化ボタンをクリックするとウインドウサイズが変わりますからこのタイミングで記録します。ただし「最適化」をした場合はサイズを記録せず、「以前の記録」を保持します。代わりに「最適化したよ」と判る印を付けます。
OnLayoutSizeChange をバイパスする仕組みはここでも必要になります。最適化を命じた時以外は、OnLayoutSizeChangeトリガのスクリプトで、ウインドウ情報を記録します。
記録する内容
何を記録するのか、そのテンプレートを定めましょう。
- ウインドウ名(あるいはレイアウト名)
- 上位置、左位置、幅と高さ(あるいは内容幅と内容高さと上部パーツサイズ)
- 最適化されているかどうかの印
こういう感じですか。幅と高さを、内容幅と内容高さ+上部パーツサイズ にしておくほうがより確実です。なぜなら、単に幅と高さではスクロールバーが表示されているかどうかで微妙に誤差が出るからです。
上部パーツサイズというのは、ツールバー、書式設定バー、テキスト定規、OSのウインドウタイトルのサイズです。これらは一部を除き表示状態に応じて正確なサイズを作り出せます。一部を除き。この一部が大問題で、別の記事にしております。
→ FileMaker スクロールバーの存在取得を困難にする書式設定バー
記録する方法
記録する方法というか、どう記録するかを含めた「記録の仕組み」です。これはいろいろな方法が考えられます。
ウインドウ名またはレイアウト名を変数名に含めたグローバル変数
以前このポストはこれについて書いていました。「$$ウインドウ名」というグローバル変数を作り、改行区切りでサイズなどを記録しました。
この方法の良い点は取り出しが簡単なことです。$$ウインドウ名ですから。弱点は、ウインドウ名ごとにグローバル変数が作られてしまい、グローバル変数だらけになってしまうことです。これわりと鬱陶しいんです。
名前にレイアウト名を含んだ変数名を計算式で作成することがこの方法の要です。それついてはこちらに詳細あります。
記録方法は、各情報を改行区切りで入れてもいいでしょう。変数名にレイアウト名が含まれるので、見つけ出すのも取り出すのも簡単です。
一つのグローバル変数にリストとして登録していく
グローバル変数を例えば $$WindowInfoList とか何とか、そういうのを用意して中身をウインドウ情報のリストにします。
この方法の良い点はグローバル変数が一個で済み簡素です。弱点は取り出すときに少々工夫が必要なことです。この工夫が煩雑で気後れしていましたが、近頃はちょっと賢い取り出し方を覚えて最早弱点ではなくなりました。
ウインドウ情報を1行で収める書き方にします。一例ですが
レイアウト名 + タブ区切り + 各サイズ(カンマ区切り)+ 最適化の印
というテンプレートにしています。レイアウト名の後ろだけタブ区切りにすることで、取り出す際に「タブを改行に置換」で「先頭レイアウト名」だけを取得することが容易くできます。
JSON
もう少し知恵が付くと、ウインドウ情報をJSON形式で記録します。慣れるとこれが断然便利です。
このあたりの話は、いつか別のポストで詳しくやるかもしれません(やらないかもしれません)
レイアウト管理テーブルを作成してレコードとして保存、管理する
いっそレイアウト管理専用テーブルを作ってレコードとして管理するのはどうだろうと、これも試したことがあります。レイアウト名、ウインドウ名、デフォルトサイズ、いろいろ仕込めます。いろいろ仕込めて楽しくて、超複雑な操作やレイアウト移動などが実現しました。
楽しいうちは良かったんですが、なんでわざわざレイアウト管理に必死にならねばならんのよ。と我ながら呆れてきます。レイアウトを作る度にレイアウトの管理に情報を記入していく作業のだるさに辟易してきて「これは趣味の世界だな」と、ようやく気づきました。
この件も面白いネタなのですが、多分詳細記事を作ることはないでしょう。だって自分もこの管理方法に飽きてしまってもうやってないから。
ウインドウを再現する
ウインドウ調整の[元に戻す] をスクリプトに置き換えた「マイ元に戻す」と言っていい作業です。記録しておいた位置とサイズを再現します。
「最適化トグル」ボタンにて使用するスクリプトになります。最適化トグルボタンは、もし [最適化の印] があれば [元に戻す] 、なければ [ 最適化して印を付ける ] という代物です。
記録した方法と書式に応じて、値を取り出してウインドウサイズにセットします。ですのでここでは具体的には示しませんが、調子に乗って「マイ元に戻す」とか言ってる自分の言葉に不信感を持ってます。
「元に戻す」で良くないか?
普通に使用するだけなら「元に戻す」だけでわりとイケます。
サイズを記録してはみたものの、実例として今現在作ってみているファイルで試したところ、「元に戻す」が意外と効いています。問題を感じません。サイズの記録なんか使わずともそこそこイケます。サイズを記録して再現するという前提でこれまで書いてきましたが、サイズの記録など不要かもしれないと思い始めています。
サイズを記録すること自体は無駄ではないです。他の用事で使います。他の用事、例えば、他のファイルのウインドウを現在ファイルのウインドウサイズと関連させて開きたいときに使ったりします。
WindowSize.fmp12 ダウンロード
幅や高さをゲットするとはどういうことのかということをかんたんに示した小さなファイルメーカー書類を作りました。
ウインドウを弄ったら数値が出てくる簡易なやつです。ダウンロードできます。
ということでウインドウサイズの調整についてでした。最初の投稿からめちゃ書き換えました。ところでトップで寝そべっているのはとめ22歳、盲目で鼻炎。この後、23歳になることなく亡くなりました。今でも亡霊が我が家に居ます。