ビュー

Wolfram言語は出力の情報を整理して表示するために使うことのできる多様なオブジェクトをサポートしている.このようなオブジェクトをまとめてビューと言い,簡単なOpenerViewから複雑で便利なTabViewまでいろいろなものがある.
このすべてに共通なのは,ビューの別のウィンドウ枠として表示される式のリストを含む第1引数を取り,オプショナルの第2引数はある時点でそのうちのどれを表示するかを決定するものであるということである.すべてどの枠を表示するかを変更するこのできるユーザインターフェースを提供する.これらはインタラクティブなデータビューアとして意図されたものである.
まず個々のビューを説明し,次にすべてあるいはほとんどに共通のオプションおよび使い方を説明する.
OpenerView
OpenerViewでは,任意の式を含むウィンドウ枠の開閉ができる.OpenerViewには常に2つの要素のリストが与えられる.最初の要素はタイトル(常に可視)に,2つ目は詳細表示三角形をクリックすると現れる内容になる.下の例では,三角形をクリックすると「Contents」という単語が現れる.
このコントロールは,詳細表示三角形が別のアプリケーションで使われる方法(MacintoshのFinderやWindowsのエクスプローラ)を真似るオブジェクトを生成するために使うことができる.通常,第2要素は下にあるように第1要素よりも大きい.
2つ以上のOpenerViewオブジェクトの列または格子を使うと,多量のデータをコンパクトな形式でブラウズできる.
タイトルは普通の文字列に限られてはいない.任意のタイプセット式やグラフィックスを使うこともできる.例えば,ここでタイトル行として,国名の他に国の輪郭を使う.
このような列(TabView等)の利点の一つは,他のビューでは通常一度に1つの枠しか見られないのに,これでは同時に2つ以上の枠を開くことができるという点である.
OpenerViewは他のビュー同様,任意の深さにネストすることができる.以下の例では,式を三角形のネストされた木に変換し,閉状態が式の頭部,開状態がそれぞれの引数に対する三角形の列にする.
すべての三角形を開状態で表示した簡単な応用例.
いくつかだけを開いた,より深くネストした例.
追加情報およびオプションの詳細はOpenerViewを参照.
TabView
TabViewは驚くほど面白いユーザインターフェースを生成することのできる豊かなオブジェクトである.式のリストを与えると,一度に1つの式を見ることのできるタブの行を持つパネルが戻る.
デフォルトで,タブは順番に番号が付いている.以下の出力では,ウィンドウ枠を選ぶためのタブをクリックする.
形式 label->contents を使うと,より説明的なタブラベルが加えられる.
もちろん内容もプログラムで生成できる.ここではTableコマンドを使い,10個の異なるプロットを生成する.
タブラベルは簡単な文字列に限られない.次ではタブラベルにタイプセットされた数式を使ってみる.
以下ではタブラベルに国の形を使い,それぞれの枠でその国のGDPのプロットを表示する.
タブラベルを上部で横に並べるときは,ラベルをある程度の長さに抑える必要がある.ControlPlacementオプションを使うと,タブをパネルのどの辺に動かすこともできる.
タブラベルが,タイプセット式,グラフィックス,動的出力を含む何でもよいということで,TabViewは思ったよりもかなり柔軟であろう.下のTabViewでは,それぞれの枠にその枠のタブのラベルが調整できるスライダーが含まれている(DynamicDynamicModule「Dynamicチュートリアル」で解説してある).
「現在表示されている枠の制御」セクションには動的なタブラベルについてのより便利な例がある.
TabViewオブジェクトは任意の深さにネストすることができるので,非常に多量の内容をコンパクトな形式で表現することができる.以下はWolframシステムの環境設定ダイアログボックスのコピーであるが,これはネストされたTabViewオブジェクトの集合として実装されている(これは完全に機能するコピーであるため,ここで何かを変更すると,実際の設定が変更される.このような複雑なダイアログボックスを,その機能性を失わずにドキュメントにコピーペーストできるということは,Wolfram言語の記号的動的インターフェーステクノロジーのパワーの一例であるといえる).
以下のダイアログボックスは通常通りに機能するので,ここで何かを変更すると直ちに初期設定に影響を及ぼすので注意すること.
追加情報およびオプションの詳細はTabViewを参照.
MenuView
MenuViewTabViewによく似ているが,どの枠を表示するかを選択するのにタブの行ではなくポップアップメニューを使う.この2つの例は「TabView」の最初の2つの例と同じである.ただTabViewの代りにMenuViewを使っただけである.
MenuViewTabViewと同じ label->value シンタックスを使うため,より説明的なラベルを指定することができる.
TabViewの場合,すべてのラベルは同時に表示される.これは設定できる枠の数に対する制約がほんのわずかであることを意味する.MenuViewは一度に1つのラベルしか表示しないので,もっとたくさん使うことができる.例えば,上の「TabView」でG7の国々の地理的タブの例題を示した.MenuViewを使うと,同じことをいくつの国に対しても行うことができる.237すべてでも可能なのである.
追加情報およびオプションの詳細はMenuViewを参照.
SlideView
SlideViewは基本的にTabViewMenuViewのようなものであるが,枠をナビゲートする最初・戻る・進む・最後というボタンがある.
枠の数は任意の大きさでよいが,ナビゲーションはスライドショーのように通過するよう限られる.
追加情報およびオプションの詳細はSlideViewを参照.
PopupView
PopupViewは一見MenuViewに似ているが,実際にはかなり異なる.MenuViewTabViewはどちらも実質的にそれぞれの枠を表す項目が2つ(ラベルと実際の内容)ある.しかしPopupViewでは1つの枠につきその枠の主たる内容の1項目しかない.
式のリストを与えると,PopupViewはそれをポップアップメニューで表示する.
PopupMenuコントロールを知っている人なら,どちらも基本的に同じもののように見えるのでどこが違うのだろうと思うかもしれない.差は意図の違いである.PopupMenuは,項目が選ばれたときに何かに影響を及ぼすコントロールとして意図されている.第1引数は必須で,現在選ばれている項目を追跡する変数を持つ.PopupViewは異なる枠が選ばれても必ずしも影響力を持たず,ただ情報を表示することだけを意図したものである.
Wolfram言語の他のコントロールやビューと同様に,PopupViewもタイプセットされた内容およびグラフィカルな内容を完全にサポートする.
追加情報およびオプションの詳細はPopupViewを参照.
FlipView
FlipViewは枠の内容を囲む目に見えるユーザインターフェースを提供しないという点で他と異なる.しかし,表示されている枠を変更するためのメカニズムは提供する.現在の枠の内容のどこかをクリックすると,次の枠の内容が表示される.
FlipViewは,最大の枠を収めるだけの大きさの固定されたサイズではなく,現在表示されている枠の大きさになるという点でも他と異なっている.これは下の「ビューのサイズ変更の制御」にあるように,FlipViewと他のビューのImageSizeオプションのデフォルト値の差分に過ぎない.
現在表示されている枠の制御
すべてのビューオブジェクトは,どの枠を現在可視にするかを指定するオプショナルの第2引数をサポートする.文字通りの値を与えると,この引数はオブジェクトが始めて生成されたときに最初に表示される枠を決定する.Dynamic変数を与えると,現在表示されている枠に外部的に影響を与えるため,あるいはそれを追跡するために使うことができる.
表示された枠に対応する第2引数の値の集合は,ビューによって異なる.
OpenerViewは通常閉じた状態で始まる.
その2つの枠はTrue(開く)とFalse(閉じる)で参照されるので,この例では開いた状態で始まる.
TabViewの枠はデフォルトで指数で参照される.
場合によっては,枠を名前で参照できるように,指数の代りに枠に記号的な識別子を与えた方がよいことがある.これには形式{id,label->contents}を使う.例えばここでは,第2引数に「6」の代りに「Japan」を使うことができる.
第2引数にDynamic変数を使うことで,別のコントロールから現在表示されている枠を制御することができるようになる(DynamicDynamicModule「Dynamicチュートリアル」に記述してある).ここでは,タブを変更できるスライダーを加える.接続は自動的に双方向となる.タブのいずれかをクリックすると,スライダーは対応する位置に移動する.
上で説明した枠を参照する指数を付けた例は,数的なSliderへの接続が簡単になるのでよい例だといえる.しかし,国名を入力することのできるテキストフィールドが欲しい場合は,名前の付いた枠があるともっと便利である.以下の例は直接国名を入力することのできるテキストフィールドを提供する.
ビューのサイズ変更の制御
ビューは常にいくつかの枠の中の1つを表示する.ビューの全体的なサイズを決定する場合に,2つの明確な方法がある.一つは現在表示されている枠を収めるのに十分な大きさのビューを作ることで,もう一つは枠を変えるたびに大きさを変えなくてすむような大きさ(各次元で最大の枠に合せる)にしておくというものである.
OpenerViewFlipView以外のすべてのビューはデフォルトで,大きさを変更する必要がないほどの大きさになっている.特にOpenerViewは開いたときに大きくならないならば,ほとんど意味がない.
ビューの動作はImageSizeオプションを使って変更することができる.ImageSize->Allではビューは最大の枠と同じ大きさになる.ImageSize->Automaticでは現在表示されている枠だけと同じ大きさになり,新しい枠になるとビューの大きさも変わる可能性がある.また,固定した数値のImageSizeを指定することもでき,その場合ビューの内容は指定された大きさに収まるようにされる.
次の2つの例を比較してみる.ImageSize->Allはデフォルトであるが,分かりやすくするために記載してある.最初の例はいつも大きいが,同じ大きさのままである.2つ目は必要に応じて大きさが変更される.
ImageSizeオプションはすべてのビューオブジェクトに対してこのように動作する.
どちらの動作の方がよいかは,場合により異なる.一般にWolframシステム以外のアプリケーションで使われるタブビューと同様のコントロールは,滅多にサイズを変更しない.そのため,従来のハードコードされたアプリケーションのように見え,またそのように動作するものを作りたい場合はImageSize->Allが適している.しかし,ImageSize->Automaticを使うと,Wolfram言語においてはダイアログボックスおよびコントロールが固定されたオブジェクトではないということが利用できる.これらのオブジェクトのサイズが変更できるので,非常に自由で柔軟なのである.
ビューの中の動的内容
このセクションでは,Dynamicメカニズムについての知識があるものと想定して話を進める(「Dynamicチュートリアル」を参照のこと).
ビューオブジェクトはすべて,妥当な位置ならどこでも完全にDynamic内容をサポートする.以下のMenuViewの例を見てみる.
この形式において,例では前もって237すべてのGDPプロットを計算し,データのない国についてはエラーを出力する.だれかがすべての国を見る可能性は薄いので,必要以上の計算を行うことになる.このコードは評価に長い時間がかかり,多量のメモリを消費する.
各ページの内容をDynamicでラップするだけで,入力はほぼ即時に評価され,ほんのわずかのメモリしか必要としない出力を生成する.
その代り,選ばれた新しい国はすぐにGDPを計算する.これは気が付かないような速さで実行される.ある国に対するエラーは,その国が選ばれたときにだけ表示される.
設定ImageSize->AllOpenerViewFlipView以外のすべてのビューのデフォルト)を使うと,オブジェクトが初めて生成されたときにビューオブジェクトの全体のサイズを決定するために,すべての枠が一度フォーマットされる.これが起らないようにするためには,ImageSizeオプションをAutomaticに設定するか,固定の数値に設定する.
(注意深い人なら,ここで細かいことに気が付くかもしれない.設定ImageSize->Allで現在可視の枠に動的内容がある場合,ビューの全体の大きさは最大の枠が現在表示されていないとしてもその大きさに依存するため,理論的には隠れた動的内容すべての値を連続的に更新する必要がある.そこで隠れた枠の更新はしないという意図的決定がなされた.その結果ImageSize->Allのビューは,新しい枠にそれが最後に表示されてから大きさの変わっている動的内容が含まれている場合,それが選ばれたときにサイズが変更できるようになった.別の方法は,隠れた枠の動作によりその大きさが変わる場合,ビューが神秘的に大きさを変えるということである.これは特異であり,あまりありえない使い方である.)
TabViewの場合,さまざまな特殊動作を実装するために動的なタブラベルを使うことができる.次の例では,現在選ばれている枠を追跡する変数にラベルを動的に依存させることにより,現在選ばれているタブがカスタム定義の方法でハイライトされる.
ビューの重要な属性の一つに,現在隠れている枠は更新されないというものがある.次の例題を見てみる.
出力が開状態の場合,マウスポインタの現在位置が表示され連続して更新されるため,一定量のCPU時間を使う.しかし,出力が閉状態では,マウス位置は追跡されずCPU時間も使われない(もちろんこれは,内容が単にマウス位置を表示することよりも計算量の多いものである場合に関係がある).
この属性によりビューのそれぞれの枠において,すべての枠を常に更新するコストをかけることなく,高価な計算を実行することのできる大きく複雑なTabViewを構築することができる.
ViewとControl
Wolfram言語には比較的低レベルのユーザインターフェースオブジェクトを表す2つのViewとControlという関数のクラスがある.ここでは関数の関数のViewクラスについて説明するが,いくつかの場合においてControlと重なる部分がある.
Viewはデータを複数の枠で提示するよう設計されており,その枠を選ぶためのユーザインターフェースを提供するため,論理的な第1引数は枠の内容を表す式のリストである.
Controlは主にDynamic接続を介して変数の値に影響を及ぼすよう設計されており,コントロール関数すべての第1引数はコントロールの値を表す引数である.
ここで混乱しそうなのが,ビューもコントロールのように変数の値を制御することができるということである.少なくともPopupViewPopupMenuでは,引数を逆にすると同一である.
これはなぜであろうか.PopupViewPopupMenuの場合,PopupViewの第2引数がオプショナル(ほとんどの場合現在表示されている枠の外部コントロールを提供する必要がないから)である便利さはあるが,単に他のViewやControl関数との一貫性のためである.PopupMenuの場合,コントロールを生成する唯一の目的は,変数を制御するためなので,第1引数はもちろんオプショナルではない.
「FlipView,PaneSelector,Toggler」で説明する集合を除いて,ビューは他のコントロールオブジェクトとはそれほど直接的に対応していない.しかし,ビューは第2引数を使ってコントロールオブジェクトとして使うこともできるということを覚えておかなければならない.それらは変数の値を制御し,それにより制御される.これがその唯一の目的ではないのである.
FlipView,PaneSelector,Toggler
非常によく似ているが同じではない3つのオブジェクトがある.それはFlipViewPaneSelectorTogglerである.これらはすべて式のリストを取り,1度にひとつを表示する.これらは引数の順序とクリック動作が異なる(しかし主に実際の動作よりも意図された動作において異なる).
FlipViewPaneSelectorは同じ引数を取る.式のリストとどの枠を表示するかを指定する数値である.異なるのはFlipViewのどこかをクリックすると次の枠に移動するが,PaneSelectorではクリックすると現在表示されている枠の内容が編集できるようになる(また別の枠に移動するユーザインターフェースはない)という点である.
Togglerは,クリックすると別の枠に移動するという点ではFlipViewと同じであるが,引数は逆の順序であり指数を最初に置く(これについては「ViewとControl」で説明している).また,TogglerはデフォルトでImageSize->Allを使うがPaneSelectorImageSize->Automaticを使う.
追加情報とオプションの詳細はFlipViewPaneSelectorTogglerを参照.