|
ノートブックの操作:カレンダーの作成
Mathematica の新しい機能により,ノートブック操作およびインターフェースデザインに多くの可能性が加わった.このノートブックでは,カレンダープログラムでそのようなツールのいくつかを説明する.
カレンダーウィンドウを生成するのに必要な評価を直ちに実行するためには,ここを押す.
月のレイアウト
第1のステップには,ノートブック操作は全く必要ない.必要なのは,各月の曜日をグリッドにレイアウトするための基本的なコードを書くことである.幸いにも,このほとんどが標準Mathematica パッケージのMiscellaneous`Calendar`に含まれている.
まず,各月の1日目が何曜日になるかを考える.曜日に1から7の番号を付けると便利である.
次に,1ヶ月に何日あるかを考える.もちろん参照テーブルを書くことも可能であるが,閏年とその他の特殊事項が正確に扱えるように,関数を書いてみる.
これで1ヶ月の全ての日にちが,7日単位に分割されたレイアウトができる.終りは空の文字列で充填される.
以下を試してみる.
うまくいっている.もう一息だ.
グリッドの作成
作成したグリッドに,カレンダーの骨子に必要な要素が入れてある.しかし,もっと見栄えをよくしたい.例えば,背景色を付けて3Dのように見せたり,日や月の名称を与えたりするには,GridBoxオブジェクトを使うと便利である.
GridBoxは,引数にリストのリストを取る.これはレイアウト関数が生成するものである.このグリッドは,長方形でなければならない.列の数が不規則数である場合は,グリッドボックスを以下のようにネストする必要がある.
ここで,ノートブック関数が初めて使われている.CellPrintは最も基本的な関数のひとつで,それが与えられるセル式を現行のノートブックに書き込む.これはPrintの動作とよく似ている.
ここでまた,曜日の略称が必要になる.月に関しても同様である.使いやすいシンボルを与えてみる.
グリッドの外観をよくする.これには,ボタンボックスを使う方法とスタイルボックスを使う方法の2通りの方法がある.ButtonBoxオブジェクトは,通常マウスクリックで引き起されるアクションを,任意のボックス式に付属させる場合に使う.この例は下で示す.ボタンボックスは3Dのビジュアル面も併せ持つ.ここでは,各ボタンの関数をNullに設定して使ってみる.これとは対照的に,StyleBoxのラッパーは一般的にオプションを囲まれたボックスに適用する.ここでは,フォント,色等のスタイル面をコントロールするオプションだけを考える.最後に,カレンダーの外観に影響するグリッドボックスのさまざまなオプションを使う.
例えば,さまざまな部分の周りにボタンボックスを置いて,色をコントロールすることができる.
行間,列間のスペースを削除すると,もっときれいに見える.ヘッダのフォントの色も変えた方がよいだろう.また,フォントもHelveticaにした方が見やすくなるだろう.フォントの変更はStyleBoxラッパーで,グリッドの割付けはGridBoxで行う.
希望の形式を作成しながら,レイアウトに次々と機能を加えていくという過程は,Mathematica では当然のことである.入力をインタラクティブに調整することによって変更をテストすることは非常に簡単である.例えば,異なる色の集合が必要とする.先行する式のRGB値を変更してテストしてみるのは,瞬時に可能である.この付加的構造により,色やフォント等の必須ではない項目を式に加える前に,レイアウトの中核をテストすることもできる.
これで希望のグリッドができた.これを関数に入れてみる.
セルとノートブックの作成
Mathematica ドキュメント(ノートブック)の基礎的な配列では,セル(テキスト,タイプセット,グラフィックス等)が階層的にネストされている.これはMathematica 式として簡単に表現できる.実際,フロントエンドは以下のようにこの形式でノートブックを保存するのである.
Notebook[{ Cell[CellGroupData[{ Cell[cell contents, style, cell options], Cell[cell contents, style, cell options] }, group state] ], Cell[cell contents, style, cell options] }, notebook options]
この形式の式を作成したら,NotebookPutコマンドを使って,フロントエンドにそれをウィンドウにするよう指示することができる.または,NotebookCreateで空のノートブックウィンドウを作り,NotebookWriteでそこに書込み,SetOptionsでオプションを設定することもできる.
この場合,パレットのようなウィンドウを作成して,月を指定するグリッドでできるだけたくさん埋めていきたい.このためには,1つのセルのノートブックを作成し,全体的な外観がコントロールできるようにそのセルとノートブックのオプションを設定する.
以下は最も簡単な例である.
これでは,セルとノートブックのオプションはすべてデフォルト値を取る.セルのデフォルトスタイルも指定する.つまり,既存のセルスタイルからの値を取らないということである.常にこのようにするわけではない.
外観を少し変更するよう,上を少し変形させてみる.
このオプションのほとんどは非常に簡単なものである.CellMarginsオプションは,{{左,右}, {下,上}}の順序でセルの周りのスペースをポイントで指定する.WindowElementsオプションは,スクロールバーやステータス領域等のノートブックレベルの事項をコントロールする.WindowFrameElementsはクローズボックス,サイズ調整領域,ズームボックス等のフレームに現れる項目である.
これまで,CellPrintを使ってセル式を現行のノートブックに書き込んできたが,式を任意のノートブックに書き込んでより繊細なコントロールがしたい場合もあるだろう.このための標準的なツールがNotebookWriteで,NotebookWrite[nbobj, cellexpr]という形式で表現される.nbobj に使える標準的なノートブックオブジェクトには,SelectedNotebook[],ButtonNotebook[],EvaluationNotebook[],InputNotebook[]等がある.特定のノートブックオブジェクト(NotebookPutで返されたものや,Notebooksによって返されたリストから選ばれたもの等)が分かっているなら,これらのノートブックのひとつと同じ場所で使うことができる.
この他のノートブック操作には,全ノートブック式をプットあるいはゲットする(NotebookPutP,NotebookGet),既存のノートブックに書き込む,あるいはそれから読み出す(NotebookWrite,NotebookRead)等が挙げられる.この他にも,選択範囲やノートブックの内容を操作するための多くの操作がある.これらはMathematica ブックに記載されている.
もうひとつの問題を処理してから,上の概念をひとつの関数に入れてみる.
インターフェースのアクション
前述のように,ボタンは物事を実行するために使うのであり,美観のためにあるのではない.このカレンダーでもうひとつ加えたい変更は,月の変更ができるようにすることである.これで最も簡単なインターフェースは,現在表示されている月からスクロースすることで,次の月や前の月に移動できるというものである.「Next」と「Previous」というボタンを作ってみる.
ボタンは,式が付属したボックス式である.この関数はButtonFunctionというオプションの中にある.任意のMathematica 関数がその関数となり得る.ButtonEvaluatorというオプションは,ボタンが関数を評価する場所を指定する.非常に限られた数の関数(ノートブック操作のみで構成されるもの)は,フロントエンドで完全に評価されるが,ほとんどの関数はMathematica カーネルに送られて評価される.専用カーネルに送られるものや,MathLink 経由で接続されている他のアプリケーションに送られるものもある.例えば,カレンダーをポップアップさせるボタンを書くために,グリッドを書くセクションで説明したテクニックを使う.
ボタン関数は実際にはMathematica の純関数で,その引数はボタンボックスの内容,ButtonDataオプション,ButtonSourceオプションで指定された場所を取る.ここでは簡単なモデルからスタートしてグローバル変数からデータを取る.
しかし,正確に言うと,プログラムの状態がノートブックに保存されているときに,グローバル変数に保存することは,あまりよい形式にはならない.情報をノートブックに格納することにより,ノートブックの状態を損失することなくセッション間でそれを保存したり開いたりすることが可能となる.次のセクションでは,これについて詳しく見てみる.
どの部分を保存すればよいだろうか.月と年が妥当であろう.
1つのボタンは月を増加してカレンダーを表示し,もうひとつのボタンは月を減らす(両方とも,年の境目で適切に前年月・次年月に変わる).
冗長なコードであるが,原則は正しい.各ボタンをクリックすると新しいウィンドウが表示される.これでは十分ではない.この問題は,最後のセクションですべてを繋ぐことで解決することができる.
カレンダーの作成
これでカレンダーアプリケーションを作成するのに必要な部分がほとんど揃った.後は現行のカレンダーグリッドを,新しいウィンドウを作成するのではなく新しいグリッドで置き換えることである.これにはいくつかの方法がある.例えば,NotebookPutはノートブックオブジェクトとして追加引数を取ることができる.この場合,指定されたノートブックはtoto で置き換えられる.別の方法として,現行の場所をノートブックのトップに動かして,ノートブックの最初のセルを選ぶというものがある.これはノートブックの構造が保障できる場合にはうまくいく.しかし,通常,次の方法の方がよく,最も強固なものといえる.ターゲットセルが生成されたときにタグを付け,NotebookFindコマンドでその場所を見付けるのである.NotebookFindは一般にノートブックの検索に使われるが,NotebookFind[notebook object, tag, All, CellTags]という特殊な形式では,タグの付いたセルを選ぶ.セルを指定するには,セルレベルでCellTags "tag"オプションを使う.
モジュラー式にすべてを組み合せて,グリッドセルを作成する関数から始める.現在の日付に色を加えて分かりやすくする.また,タイトルと共に月を変えるボタンを置く.原則的には単純にmonthgridを再コード化するが,既存のコードベースで作業する例として,現行の結果を変換する.
現在の月を増やす,あるいは減らすためのボタン関数は,1つの関数にすることができる.ここでは,どちらに進めたいかによりopをIncrementあるいはDecrementとする.
カレンダーの状態を適切に保存するという問題も解決できる.グローバル変数に依存するのではなく,ノートブックで現在の月を保存するのである.これで複数のカレンダーが保持できる.カレンダーを保存して,一旦サポートする関数が評価されると動作するようにすることもできる.任意のMathematica 式をノートブック,セル,スタイルボックスレベルで保存するために使える,TaggingRulesというオプションがある.規則として,TaggingRulesでは"tagstring" valueのリストを保存し,複数のオーバーラップした使用も可能である.ここで,Options[ButtonNotebook[], TaggingRules]でアクセス可能なノートブック全体に関連付けられたTaggingRulesを使う.タグの文字列は"CalendarInformation"と呼ぶ.
状態を初期化し,ノートブックを作成するユーザレベルの関数を書く.
MakeCalendarは標準的なMathematica の日付形式を受け入れる.
試してみよう.
もちろんもっとたくさんの変更を加えることも可能である.例えば,毎日がボタンになっているのでそこから予定表,もしくはその日に関連したデータにアクセスできるようにすることもできる.また,日付は株の実績や最高気温等のお気に入りのデータ用にカラーコードすることもできる.
ノートブック操作方法にはこの他にも多数あるが,この例では使用できるツールのいくつかをご紹介した.
|