Max 5 API Reference
あなたのオブジェクトはパッチのスクリプティング機能を利用して、パッチの名前、階層、あなたのオブジェクトに対するピアオブジェクトなどのような、パッチのコンテキストについて知ることができます。
さらに、パッチを変更することもできますが、ランタイムバージョンでは、オブジェクトによるこのような操作が実行できないため、動作しません。
あなたのオブジェクトを内部に持つ patcher オブジェクトを取得するために、obex ハッシュテーブルを使うことができます。obex("object extention" の略)は、より一般的には、オブジェクト内にデータを格納し、呼び戻す手段です。しかし、ここでは obex をリードオンリー(読み出し専用)で使用するだけです。
SDK の前のバージョンで説明されているテクニックとは異なり、パッチを見つけるための obex の使用は、インスタンス生成ルーチン(new instance ルーチン)だけではなく、任意の箇所で行なうことができる点に注意して下さい。
void myobject_getmypatcher(t_myobject *x) { t_object *mypatcher; obex_object_lookup(x, gensym("#P"), &mypatcher); post("my patcher is at address %lx",mypatcher); }
パッチは不透明な(訳注:ブラックボックスのような)Max オブジェクトです。パッチ内のデータにアクセスするためには、アトリビュートやメソッドを使います。
パッチの名前とそのファイルパス(もしあれば)を取得するためには、次に示すようなアトリビュートの値を取得します。
t_symbol *name = object_attr_getsym(patcher, gensym("name")); t_symbol *path = object_attr_getsym(patcher, gensym("filepath"));
これらのアトリビュートは、NULL あるいは空のシンボルを返す可能性があります。
あなたのオブジェクトを含んでいるパッチから上のパッチの階層を見つけるために、 jpatcher_getparentpatcher() を使うことができます。パッチの parent が NULL であれば、トップレベルのパッチです。階層を上りながら、それぞれの親パッチの名前を表示するループを次に示します。
t_object *parent, *patcher; t_symbol *name; object_obex_lookup(x, gensym("#P"), &patcher); parent = patcher; do { parent = jpatcher_getparentpatcher(parent); if (parent) { name = object_attr_getsym(parent, gensym("name")); if (name) post("%s",name->s_name) } } while (parent != NULL);
パッチ内の最初のオブジェクトを取得するためには jpatcher_get_firstobject() を使います。それに続くオブジェクトはjbox_get_nextobject() で取得できます。
まだ UI オブジェクトの分析 をお読みになっていないのであれば、次の点に留意して下さい。パッチは非 UI オブジェクトのリストを直接は保持していません。その代わり、box という名前の UI オブジェクトのリストを保持しています。そして、非UI オブジェクトを内包している box は newobj と呼ばれます。 jpatcher_get_firstobject() などを呼び出して取得した「オブジェクト」はbox です。 jbox_get_object() ルーチンを使うと、box が UIオブジェクトであっても、あるいは、非 UI オブジェクトを内包する newobj であっても、その実際のオブジェクトへのポインタを取得できます。dial や slider のような UI オブジェクトの場合 jbox_get_object() によって返されるポインタは box と同じです。しかし、非 UI オブジェクトでは、ポインタは異なったものになります。
次に示す例は、オブジェクトが含まれるパッチの中にある(box 内の)すべてのオブジェクトのクラスを表示する関数です。
void myobject_printpeers(t_myobject *x) { t_object *patcher, *box, *obj; object_obex_lookup(x, gensym("#P"), &patcher); for (box = jpatcher_get_firstobject(patcher); box; jbox_get_nextobject(box)) { obj = jbox_get_object(box); if (obj) post("%s",object_classname(obj)->s_name); else post("box with NULL object"); } }
上記のテクニックの代わりに、コールバック関数を書き、パッチのイタレーション(繰り返し処理)サービスを利用することができます。イタレーションを使用することの利点は、サブパッチを内包している可能性がある様々なオブジェクト(patcher、poly~、bpatcherなど)の詳細を知らなくても、パッチ階層を降りていくことができることにあります。パッチ階層のある1つのレベルだけで繰り返しを行ないたい場合でも、この方法を利用できます。
イタレーションを利用する関数は次のように定義します。これはパッチ内のすべての box(また、指定すればパッチ内にあるすべてのサブパッチ) で呼び出されます。
long myobject_iterarator(t_myobject *x, t_object *b);
この関数は、イタレーションを継続する必要がある場合には 0、停止する必要がある場合には 1 を返します。これにより、特定のオブジェクトを検索する方法として、イタレータを使用することが可能になります。
次に示すのは、イタレータ関数を利用した例です。
t_object *patcher; long result = 0; patcher = object_obex_lookup(x, gensym("#P"), &patcher); object_method(patcher, gensym("iterate"), myobject_iterator, (void *)x, PI_WANTBOX | PI_DEEP, &result);
PI_WANTBOX フラグは、パッチのイタレータに対し、box に内包されるオブジェクトではなく、box をイタレータ関数に渡すよう指示するものです。 PI_DEEP フラグは、イタレーションが降順、深さ優先で、サブパッチ内部まで行なわれることを意味します。result というパラメータはイタレータによって最後に返された値を返します。例えば、非ゼロの値が返されてイタレータがすぐに終了した場合、その値が保持されています。イタレータ関数がなかなか終了しない場合、result は 0 になります。
イタレータ関数が box を受け取るものと仮定した場合、次のイタレータの例では、パッチ内にあるすべてのオブジェクトのクラス名とスクリプトでの名前(名前がある場合)が出力されます。私たちが知ろうとするクラスが box に関連づけられたオブジェクトであるのに対し、スクリプトでの名前(scripting name)が box のアトリビュートである点に注意して下さい。
long myobject_iterator(t_myobject *x, t_object *b) { t_symbol *name = object_attr_getsym(b, gensym("varname")); t_symbol *cls = object_classname(jbox_get_object(b)); if (name) post("%s (%s)",cls->s_name, name->s_name); else post("%s", cls->s_name); return 0; }
ほとんどの Max ユーザインターフェイスはパッチャースクリプティングを使って実装されています。例えば、インスペクタは、inspector オブジェクトが内部で生成されたパッチです。ファイルブラウザウィンドウは、スクリプトによって生成されたそれぞれ別のオブジェクトを4〜5個持っています。デバッグウィンドウでさえ、動的にスクリプトによって生成されるパッチです。このような例を述べたのは、パッチ内でのオブジェクトの生成が実際に(すべての詳細を正確に得るとすれば)どのように動作するかについての情報を提供するためです。xxx サンプルオブジェクトは、パッチャースクリプティングを使って「編集ウィンドウ(editing window)」を生成する方法を示しています。このウィンドウは table や buffer~ オブジェクトをダブルクリックした際に表示されるウィンドウと同様なものです。
パッチ内にオブジェクトを作る場合、一般的に、 Dictionary (前述の UI オブジェクトの説明を参照して下さい)を使用する必要があります。しかし、いくつかの複雑な処理を省くために、便利な関数 newobject_sprintf() を使うことができます。
オブジェクトを生成するために、いくつかのアトリビュートを設定します。指定する値がない場合、オブジェクトのアトリビュートはデフォルト値に設定されますが、少なくともオブジェクトの位置の指定は行なわなければならないでしょう。次に示すのは、アトリビュートの構文解析とsprintf の組み合わせを利用して、toggl と metro オブジェクトを生成している例です。 newobject_sprintf() によるオブジェクトの生成に興味があれば、Max ドキュメントを調べて、オブジェクトの指定に用いられる "アトリビュート名 - 値" の組み合わせに関する記述を参照して下さい。
t_object *patcher, *toggle, *metro; patcher = object_obex_lookup(x, gensym("#P"), &patcher); toggle = newobject_sprintf(patcher, "@maxclass toggle @patching_position %.2f %.2f", x->togxpos, x-> togxpos); metro = newobject_sprintf(patcher, "@maxclass newobj @text metro 400 @patching_position %.2f %.2f", x->metxpos, x->metypos);
非UI オブジェクトを生成する場合、newobj に maxclass アトリビュートを設定し、text アトリビュートをオブジェクトボックスに表示されるテキストに設定するということを覚えておいて下さい。アトリビュートは任意の順序で指定することができます。patching_position アトリビュートを使うと、オブジェクトの左上隅の位置だけを指定でき、デフォルトのサイズでオブジェクトが生成されます。text オブジェクトにより、オブジェクトのデフォルトサイズはパッチのデフォルトフォントサイズに基づいたものになります。。
最後に newobject_sprintf() が新しく生成された box へのポインタを返すという点に注意して下さい。これは、box 内に生成された新しいオブジェクトへのポインタではありません。box 内のオブジェクトを取得するためには j jbox_get_object() を使用します。
2つのオブジェクト間の接続を行なうスクリプトを書きたい場合、パッチにメッセージを送信することによってこれを実現できます。上記のパッチのような、toggle オブジェクト、metro オブジェクトがあると仮定した場合、次のようにアトム(atom)の配列を作り、 object_method_typed() を使ってメッセージを送信します。
t_atom msg[4], rv; atom_setobj(msg, toggle); // 接続元 (source) atom_setlong(msg + 1, 0); // アウトレットナンバ (左端が 1) atom_setobj(msg + 2, metro); // 接続先 (destination) atom_setlong(msg + 3, 0); // インレットナンバ (左端が 1 ) object_method_typed(patcher, gensym("connect"), 4, msg, &rv);
非表示の接続にしたい場合には、第5のアーギュメントを追加し、これを任意の負の数値に設定して渡します。
パッチ内のオブジェクトを削除する場合 object_free() を呼び出すだけでは不十分です。その代わりに jpatcher_deleteobj() を使います。Max のバージョン 5.0.6 現在では、これによりオブジェクトに接続されたすべてのパッチコードを取り除き、パッチの再描画を行ないます。
パッチ内のオブジェクトやパッチ自体ののアピアランスや動作を変更するために、オブジェクトアトリビュート関数を使用することができます。これらのアトリビュートの中でユーザが変更できるものは僅かであるということを覚えておいて下さい。C レベルでアクセスできるアトリビュートはそれよりもずっと広範囲に渡っています。
object 型のアトリビュートには object_attr_getobj()/object_attr_seobj() を介してアクセスできます。char 型のアトリビュートには object_attr_getchar()/object_attr_setchar() でアクセスできます。long 型のアトリビュートは、 object_attr_getlong() / object_attr_setlong() によってアクセスできます。シンボル型のアトリビュートには、 object_attr_getsym() / object_attr_setsym() を介してアクセスできます。色や矩形領域を表すような、配列によるアトリビュートには、object_attr_getvalueof() / object_attr_setvalueof() を使います。
アトリビュート名 | 型 | 設定の可/不可 | 説明 |
box | object | 不可 | パッチを内包するボックス (NULLならばトップレベルパッチ) |
locked | char | 可 (not in runtime) | パッチのロック状態 |
presentation | char | 可 | パッチのプレゼンテーションモード |
openinpresentation | char | 可 | パッチをプレゼンテーションモードで開くかどうか? |
count | long | 不可 | パッチ内のオブジェクト数 |
fgcount | long | 不可 | パッチのフォアグラウンドレイヤーのオブジェクト数 |
bgcount | long | 不可 | パッチのバックグラウンドレイヤーのオブジェクト数 |
numvews | long | 不可 | パッチの、現在開かれているビューの数 |
numwindowviews | long | 不可 | パッチの、現在開かれているウィンドウベースのビューの数 |
firstobject | object | 不可 | パッチの最初の box |
lastobject | object | 不可 | パッチの最後の box |
firstline | object | 不可 | パッチの最初のパッチコード |
firstview | object | 不可 | パッチの最初のビューオブジェクト |
title | symbol | 可 | ウィンドウタイトル |
fulltitle | symbol | 不可 | "unlocked"などを含む完全なタイトル |
name | symbol | 不可 | 名前 (タイトルとは別に設定できます) |
filename | symbol | 不可 | ファイル名 |
filepath | symbol | 不可 | ファイルパス (プラットフォームに依存しないファイルパス構文) |
fileversion | long | 不可 | ファイルのバージョン |
noedit | char | 不可 | パッチをアンロック状態にできるかどうか |
collective | object | 不可 | パッチがコレクティブ内にある場合のコレクティブオブジェクト |
cansave | char | 不可 | パッチを保存できるかどうか |
dirty | char | 可 (not in runtime) | パッチが変更されたかどうか |
bglocked | char | 可 | バックグラウンドがロックされているかどうか |
rect | double[4] | 可 | パッチの矩形領域 (左、上、幅、高さ) |
defrect | double[4] | 可 | パッチのデフォルトの矩形領域 (最初に開いたときに使用) |
openrect | double[4] | 可 | 固定された内部ウィンドウの位置 |
parentpatcher | object | 不可 | すぐ上のレベルの親パッチ (NULLならばトップレベルパッチ) |
toppatcher | object | 不可 | 最上位の親パッチ (NULL ならばトップレベルパッチ) |
parentclass | object | 不可 | 親パッチの クラスオブジェクト(patcher, poly~, bpatcherなど) |
bgcolor | double[4] | 可 | ロック時のバックグラウンドカラー (RGBA) |
editing_bgcolor | double[4] | 可 | アンロック時のバックグラウンドカラー (RGBA) |
edit_framecolor | double[4] | 可 | テキスト編集フレームの色 |
locked_iocolor | double[4] | 可 | ロック時のインレット/アウトレットの色 |
unlocked_iocolor | double[4] | 可 | アンロック時のインレット/アウトレットの色 |
boguscolor | double[4] | 可 | 初期化されていない (偽の) オブジェクトの色 |
gridsize | double[2] | 可 | 編集グリッドサイズ |
gridonopen | char | 可 | パッチを開いたときにグリッドを表示 |
gridsnapopen | char | 可 | パッチを開いたときに、グリッドにスナップ |
imprint | char | 可 | デフォルト値のオブジェクトアトリビュートを保存 |
defaultfocusbox | symbol | 可 | デフォルトでフォーカスを与えるbox (変数名) |
enablehscroll | char | 可 | 水平スクロールバーの表示 |
enablevscroll | char | 可 | 垂直スクロールバーの表示 |
boxanimatetime | long | 可 | box のアニメーションタイム |
default_fontname | symbol | 可 | デフォルトフォントの名前 |
default_fontface | long | 可 | デフォルトの "fake" フォントフェース (0 プレーン, 1, ボールド, 2 イタリック, 3 ボールドイタリック) |
default_fontsize | long | 可 | デフォルトのフォントサイズ(ポイント単位) |
toolbarvisible | char | 可 | パッチを開いたときにツールバーを表示 |
toolbarheight | long | 可 | ツールバーの高さ (非表示の場合は 0 を使用) |
toolbarid | symbol | 可 | ツールバーの名前(maxinterface.json) , none = 空のシンボル |
アトリビュート名 | 型 | 設定の可/不可 | 説明 |
rect | double[4] | 設定のみ | patching_rectと presentation_rect の両方を変更 |
presentation_rect | double[4] | 可 | プレゼンテーションモードでの矩形領域 |
patching_rect | double[4] | 可 | 編集モード(patching mode)での矩形領域 |
position | double[2] | 設定のみ | patching_position と presentation_position の両方を変更 |
size | double[2] | 設定のみ | patching_size と presentation_size の両方を変更 |
patching_position | double[2] | 可 | 編集モードでの位置 (上、左端) |
presentation_position | d[2] | 可 | プレゼンテーションモードでの位置 |
patching_size | double[2] | 可 | 編集モードでのサイズ (幅、高さ) |
presentation_size | double[2] | 可 | プレゼンテーションモードでのサイズ |
maxclass | symbol | 不可 | Max クラスのクラス名 (非UI オブジェクトの newobj) |
object | object | 不可 | 関連づけられたオブジェクト (jbox_get_object と等価) |
patcher | object | 不可 | パッチを内包している |
hidden | char | 可 | ロックされた場合に box を非表示にするかどうか? |
fontname | symbol | 可 | フォント名(boxが font アトリビュート、またはテキストフィールドを持っている場合) |
fontface | long | 可 | "Fake" フォントフェイス (boxが font アトリビュート、またはテキストフィールドを持っている場合) |
fontsize | long | 可 | フォントサイズ (boxが font アトリビュート、またはテキストフィールドを持っている場合) |
textcolor | double[4] | 可 | テキスト色 (boxが font アトリビュート、またはテキストフィールドを持っている場合) |
hint | symbol | 可 | 関連づけられているヒント |
color | double[4] | 可 | 標準の color アトリビュート (すべてのオブジェクトで存在するわけではありません) |
nextobject | object | 不可 | パッチのリストにある次のオブジェクト |
prevobject | object | 不可 | パッチのリストにある前のオブジェクト |
varname | symbol | 可 | スクリプティングで用いる名前 |
id | symbol | 不可 | 変更されないオブジェクト ID (ファイルに保存) |
canhilite | char | 不可 | このオブジェクトがフォーカスを受け入れるかどうか? |
background | char | 可 | バックグラウンドに含まれている/p> |
ignoreclick | char | 可 | クリックを無視する |
maxfilename | symbol | 不可 | クラスがエクスターナルの場合、そのファイル名 |
description | symbol | 不可 | アシスタンスで使用される説明 |
drawfirstin | char | 不可 | 左端のインレットを描画するかどうか? |
growy | char | 不可 | 固定されたアスペクト比でオブジェクトを拡大表示できるか? |
growboth | char | 不可 | 幅と高さがそれぞれ独立した形でオブジェクトを拡大表示できるか? |
nogrow | char | 不可 | オブジェクトのサイズが固定されているか? |
mousedragdelta | char | 不可 | オブジェクトが、非表示のマウストラッキングを使用するか (ナンバーボックス) |
textfield | object | 不可 | このボックスに関連づけられた textfield オブジェクトが存在すれば、そのオブジェクト |
editactive | char | 不可 | アンロック状態のパッチで、オブジェクトが現在フォーカスされているボックスかどうか? |
prototypename | symbol | 不可 | このオブジェクトの作成に使用されたプロトタイプファイルのファイル名 |
presentation | char | 可 | オブジェクトがプレゼンテーションに含まれるか? |
annotation | symbol | 可 | オブジェクト上にマウスが置かれたときに、クルーウィンドウに表示されるテキスト |
numinlets | long | 不可 | 可視のインレット数 |
numoutlets | long | 不可 | 可視のアウトレット数 |
outlettype | symbol[] | 不可 | アウトレットの型によるシンボルの配列("signal"など) |
非UI オブジェクトのアトリビュートにアクセスするためには、box に対して jbox_get_object() を使い、非UI オブジェクトを最初に取得します。