
:mod:`FrameWork` --- 対話型アプリケーション・フレームワーク
===========================================================

.. module:: FrameWork
   :platform: Mac
   :synopsis: 対話型アプリケーション・フレームワーク
   :deprecated:


:mod:`FrameWork` モジュールは、対話型 Macintosh アプリケーションのク\
ラスで、同時にフレームワークを提供します。プログラマは、サブクラスを作っ\
て基底クラスの様々なメソッドをオーバーライドし、必要な機能を実装するこ\
とでアプリケーションを組み立てられます。機能のオーバーライドは、時によっ\
て様々な異なるレベルで行われます。つまり、ある一つのダイアログウィンド\
ウでクリックの処理を普段と違う方法で行うには、完全なイベント処理をオー\
バーライドする必要はありません。

.. warning::

   このモジュールは 3.0 で削除されます。

:mod:`FrameWork` の開発は事実上停止しています。現在では :mod:`PyObjC`
を使用すれば Python から Cocoa の全機能を使用することがで\
きます。このドキュメントでは最も重要な機能だけしか記述していませんし、
それさえも論理的な形で書かれてもいません。ソースか例題を詳しく見てくだ\
さい。次にあげるのは、MacPython ニュースグループにポストされたコメントで、
:mod:`FrameWork` の強力さと限界について述べています。


.. epigraph::

   :mod:`FrameWork` の最大の強みは、制御の流れをたくさんの異なる部分に\
   分割できることです。例えば :mod:`W` を使って、いろいろな方法でメ\
   ニューをオン/オフしたり、残りをいじらずにうまくプラグインさせることが\
   できます。 :mod:`FrameWork` の弱点は、コマンドインタフェースが抽象化\
   されていないこと(といっても難しいわけではないですが)、ダイアログサポー\
   トが最低限しかないこと、それからコントロール/ツールバーサポートが全く\
   ないことです。

:mod:`FrameWork` モジュールは次の関数を定義しています。

.. function:: Application()

   アプリケーション全体を表現しているオブジェクト。メソッドについての詳細\
   は以下の記述を参照してください。デフォルト :meth:`__init__` ルーチ\
   ンは、空のウィンドウ辞書とアップルメニューつきのメニューバーを作成します。


.. function:: MenuBar()

   メニューバーを表現するオブジェクト。このオブジェクトは普通はユーザは\
   作成しません。


.. function:: Menu(bar, title[, after])

   メニューを表現するオブジェクト。生成時には、メニューが現われる  ``MenuBar`` と、
   *title* 文字列、メニューが表示されるべき(1から始まる)位置 *after*
   (デフォルトは末尾)を渡します。


.. function:: MenuItem(menu, title[, shortcut, callback])

   メニューアイテムオブジェクトを作成します。引数は作成するメニューと、ア\
   イテムのタイトル文字列、オプションのキーボードショートカット、コールバッ\
   クルーチンです。コールバックは、メニューID、メニュー内のアイテム番号(1\
   から数える)、現在のフロントウィンドウ、イベントレコードを引数に呼ばれ\
   ます。

   呼び出し可能なオブジェクトのかわりに、コールバックは文字列でも良いです。
   この場合、メニューの選択は、最前面のウィンドウとアプリケーションの中で\
   メソッド探索を引き起こします。メソッド名は、コールバック文字列の前に
   ``'domenu_'`` を付けたものです。

   ``MenuBar`` の :meth:`fixmenudimstate` メソッドを呼びだすと、現在\
   のフロントウィンドウにもとづいて、適切なディム化を全てのメニューアイテ\
   ムに対してほどこします。


.. function:: Separator(menu)

   メニューの最後にセパレータを追加します。


.. function:: SubMenu(menu, label)

   *label* の名前のサブメニューを、メニュー *menu* の下に作成しま\
   す。メニューオブジェクトが返されます。


.. function:: Window(parent)

   (モードレス)ウィンドウを作成します。 *Parent* は、ウィンドウが属す\
   るアプリケーションオブジェクトです。作成されたウィンドウはまだ表示され\
   ません。


.. function:: DialogWindow(parent)

   モードレスダイアログウィンドウを作成します。


.. function:: windowbounds(width, height)

   与えた幅と高さのウィンドウを作成するのに必要な、
   ``(left, top, right, bottom)`` からなるタプルを返します。ウィ\
   ンドウは以前のウィンドウに対して位置をずらして作成され、全体のウィンド\
   ウが画面からなるべく外れないようにします。しかし、ウィンドウはいつでも\
   全く同じサイズで、そのため一部は画面から隠れる場合もあります。


.. function:: setwatchcursor()

   マウスカーソルを時計型に設定します。


.. function:: setarrowcursor()

   マウスカーソルを矢印型に設定します。


.. _application-objects:

アプリケーションオブジェクト
----------------------------

アプリケーションオブジェクトのメソッドは各種ありますが、次のメソッドを\
あげておきます。


.. method:: Application.makeusermenus()

   アプリケーションでメニューを使う必要がある場合、このメソッドをオーバー\
   ライドします。属性 :attr:`menubar` にメニューを追加します。


.. method:: Application.getabouttext()

   このメソッドをオーバーライドすることで、アプリケーションの説明を記述す\
   るテキスト文字列を返します。代わりに、 :meth:`do_about` メソッドをオー\
   バーライドすれば、もっと凝った"アバウト"メッセージを出す事ができます。


.. method:: Application.mainloop([mask[, wait]])

   このルーチンがメインイベントループで、作成したアプリケーションが動き出\
   すためにはこれを呼ぶことになります。 *Mask* は操作したいイベントを\
   選択するマスクです。 *wait* は並行に動作しているアプリケーションに\
   割り当てたいチック数(1/60秒)です(デフォルトで 0 ですが、あまり良い値で\
   はありません)。 *self* フラグを立ててメインループを抜ける方法はまだ\
   サポートされていますが、これはお勧めできません。代わりに
   ``self._quit()`` を呼んでください。

   イベントループは小さなパーツに分割されていて、各々をオーバーライドでき\
   るようになっています。これらのメソッドは、デフォルトでウィンドウとダイ\
   アログや、ドラッグとリサイズの操作、 AppleEvent、非FrameWorkのウィンド\
   ウに関するウィンドウの操作などに関するイベントを分岐することなどまで面\
   倒をみてくれます。

   原則として、全てのイベントハンドラは、イベントが完全に取り扱われた場合\
   は ``1`` を返さなくてはいけませんし、それ以外では ``0`` を返さな\
   くてはいけません(例えば、前面のウィンドウは FrameWork ウィンドウではな\
   い場合を考えてください)。こうしなくてはいけない理由は、アップデートイ\
   ベントなどが Sioux コンソールウィンドウなどの他のウィンドウにきちんと渡さ\
   れるようにするためです。 *our_dispatch* やその呼び出し元の内部から
   :func:`MacOS.HandleEvent` を呼んではいけません。そうしたコードが Python
   の内部ループのイベントハンドラを経由して呼ばれると、無限ループ\
   になりかねないからです。


.. method:: Application.asyncevents(onoff)

   非同期でイベント操作をしたい場合は、非ゼロの引数でこのメソッドを呼んで\
   ください。こうすることで、イベントが生じた時に、内部のインタプリタのルー\
   プで、アプリケーションイベントハンドラ *async_dispatch* が呼ばれる\
   ことになります。すると、長時間の計算を行っている場合でも、FrameWorkウィ\
   ンドウがアップデートされ、ユーザーインターフェースが動き続けるようにな\
   ります。ただし、インタプリタの動作が減速し、非リエントラントのコード
   (例えばFrameWork自身など)に奇妙な動作が見られるかもしれません。デフォル\
   トでは *async_dispatch* はすぐに *our_dispatch* を呼びますが、
   このメソッドをオーバーライドすると、特定のイベントを非同期で操作しても\
   良くなります。処理しないイベントは Sioux などに渡されることになります。

   onあるいはoff値が返されます。


.. method:: Application._quit()

   実行中の :meth:`mainloop` 呼び出しを、次の適当なタイミングで終了さ\
   せます。


.. method:: Application.do_char(c, event)

   ユーザーが文字 *c* をタイプした時に呼ばれます。イベントの全詳細は
   event 構造体の中にあります。このメソッドはウィンドウオブジェクト内で使\
   うためにも提供されています。このオブジェクトのウィンドウが最前面にある\
   場合は、アプリケーション全般について本ハンドラをオーバーライドします。


.. method:: Application.do_dialogevent(event)

   イベントループ内部で最初に呼ばれて、モードレスダイアログイベントを処理\
   します。デフォルトではメソッドは単にイベントを適切なダイアログに分岐す\
   るだけです(関連したダイアログウィンドウオブジェクトを経由してではあり\
   ません)。特別にダイアログイベント(キーボードショートカットなど)を処理す\
   る必要がある場合にオーバーライドしてください。


.. method:: Application.idle(event)

   イベントが無い場合にメインイベントループから呼ばれます。 null イベン\
   トも渡されます(つまりマウス位置などを監視することができます)。


.. _window-objects:

ウィンドウオブジェクト
----------------------

ウィンドウオブジェクトは特に次のメソッドを持ちます。


.. method:: Window.open()

   ウィンドウを開く時はこのメソッドをオーバーライドします。Mac OS ウィンド\
   ウ ID を :attr:`self.wid` に入れて :meth:`do_postopen` メソッドを\
   呼ぶと、親アプリケーションにウィンドウを登録します。


.. method:: Window.close()

   ウィンドウを閉じるときに特別な処理をする場合はこのメソッドをオーバーラ\
   イドします。親アプリケーションからウィンドウの登録を削除するには、
   :meth:`do_postclose` を呼びます。


.. method:: Window.do_postresize(width, height, macoswindowid)

   ウィンドウがリサイズされた後に呼ばれます。 ``InvalRect`` を呼び出す\
   以外にもすることがある場合はこれをオーバーライドします。


.. method:: Window.do_contentclick(local, modifiers, event)

   ウィンドウのコンテント部分をユーザーがクリックすると呼ばれます。引数は\
   位置座標(ウィンドウを基準)、キーモディファイア、生のイベントです。


.. method:: Window.do_update(macoswindowid, event)

   ウィンドウのアップデートイベントが受信された時に呼ばれます。ウィンドウ\
   を再描画します。


.. method:: Window.do_activate(activate, event)

   ウィンドウがアクティブ化(``activate == 1``)、非アクティブ化\
   (``activate == 0``)する際に呼ばれます。フォーカスのハイライト\
   などを処理します。


.. _controlswindow-object:

コントロールウィンドウオブジェクト
----------------------------------

コントロールウィンドウオブジェクトには ``Window`` オブジェクトのメ\
ソッドの他に次のメソッドがあります。


.. method:: ControlsWindow.do_controlhit(window, control, pcode, event)

   コントロール *control* のパートコード *pcode* がユーザにヒットされた\
   場合に呼ばれます。トラッキングなどは任せておいてかまいません。


.. _scrolledwindow-object:

スクロールウィンドウオブジェクト
--------------------------------

スクロールウィンドウオブジェクトは、次のメソッドを追加したコントロール\
ウィンドウオブジェクトです。


.. method:: ScrolledWindow.scrollbars([wantx[, wanty]])

   水平スクロールバーと垂直スクロールバーを作成します(あるいは破棄します)。
   引数はどちらが欲しいか指定します(デフォルトは両方)。スクロールバーは常\
   に最小値 ``0`` 、最大値 ``32767`` です。


.. method:: ScrolledWindow.getscrollbarvalues()

   このメソッドは必ず作っておかなくてはいけません。現在のスクロールバーの\
   位置を与えるタプル ``(x, y)`` を(``0`` の  ``32767``
   間で)返してください。バーの方向について全文書が可視状態で\
   あること知らせるため ``None`` を返す事もできます。


.. method:: ScrolledWindow.updatescrollbars()

   文書に変更があった場合はこのメソッドを呼びます。このメソッドは
   :meth:`getscrollbarvalues` を呼んでスクロールバーを更新します。


.. method:: ScrolledWindow.scrollbar_callback(which, what, value)

   あらかじめ与えておくメソッドで、ユーザーとの対話により呼ばれます。
   *which* は ``'x'`` か ``'y'`` 、
   *what* は ``'-'``, ``'--'``, ``'set'``, ``'++'``, ``'+'`` のどれかです。
   ``'set'`` の場合は、 *value* に新しいスクロールバー位置を入れておきます。


.. method:: ScrolledWindow.scalebarvalues(absmin, absmax, curmin, curmax)

   :meth:`getscrollbarvalues` の結果から値を計算するのを助ける補助的な\
   メソッドです。文書の最小値と最大値、可視部分に関する最先頭値(最左値)と\
   最底値(最右値)を渡すと、正しい数か ``None`` を返します。


.. method:: ScrolledWindow.do_activate(onoff, event)

   ウィンドウが最前面になった時、スクロールバーのディム(dimming)/ハイライ\
   トの面倒をみます。このメソッドをオーバーライドするなら、オーバーライド\
   したメソッドの最後でオリジナルのメソッドを呼んでください。


.. method:: ScrolledWindow.do_postresize(width, height, window)

   スクロールバーを正しい位置に移動させます。オーバーライドする時は、オー\
   バーライドしたメソッドの一番最初でオリジナルのメソッドを呼んでください。


.. method:: ScrolledWindow.do_controlhit(window, control, pcode, event)

   スクロールバーのインタラクションを処理します。これをオーバーライドする\
   時は、オリジナルのメソッドを最初に呼び出してください。非ゼロの返り値は\
   スクロールバー内がヒットされたことを意味し、実際に処理が進むことになり\
   ます。


.. _dialogwindow-objects:

ダイアログウィンドウオブジェクト
--------------------------------

ダイアログウィンドウオブジェクトには、 ``Window`` オブジェクトのメソッ\
ドの他に次のメソッドがあります。


.. method:: DialogWindow.open(resid)

   ID *resid* の DLOG リソースからダイアログウィンドウを作成します。
   ダイアログオブジェクトは :attr:`self.wid` に保存されます。


.. method:: DialogWindow.do_itemhit(item, event)

   アイテム番号 *item* がヒットされた時に呼ばれます。トグルボタンなど\
   の再描画は自分で処理してください。

