前のページ次のページ上に戻るホーム BREW C++ ライブラリ & GUI フレームワーク & XML ミドルウェア : SophiaFramework UNIVERSE 5.0

9.2. レスポンダシステムを構成する要素

レスポンダシステムには、有効・可視・活性・操作可能・フォーカスといった状態や、 領域、親子・姉妹関係、イベント、トレーサ、ハンドラなどの重要な要素がいくつかあります。

これらは SFYResponder クラスで定義、実装されており、 すべての GUI コンポーネント(レスポンダ)で共通の概念となっています。

この節では、レスポンダシステムを構成するこれらの要素について説明します。

関連情報 : レスポンダシステムの機能

9.2.1. タイプ

タイプとは、レスポンダ毎に必ず定義する必要のある4文字(4バイト)の識別子のことです。

タイプはコンストラクタ内で設定され、以後変更されることはありません。

four_char_code マクロ関数を利用して「4文字リテラル」として設定します。

抽象クラスのポインタを介してレスポンダを参照する場合に、具象クラスを特定するために利用することができます。

[Caution] 注意事項

タイプは新たにレスポンダを定義するとき必ずコンストラクタ内で設定する必要があります。

小文字アルファベットまたは記号からなる4文字リテラルは SophiaFramework UNIVERSE で予約されています。 アプレット開発用には、大文字アルファベット 4 文字からなる 4 文字リテラルを利用します。

関連情報 : タイプ一覧

例 9.4. タイプの設定

USRResponder::USRResponder(Void) static_throws
{
    if (static_try()) {

        // タイプは必ずこの場所で設定する
        // このようにすると親クラスのコンストラクタ内でエラーが発生した場合は
        // 親クラスのタイプが保持され、自クラスのコンストラクタ内でエラーが
        // 発生した場合は自クラスのタイプが設定されるようになる
        // 外部からこのクラスを利用する場合にエラーの発生個所を特定しやすくなる
        SetType(four_char_code('U', 'R', 'S', 'P'));

        // その他の初期化処理を記述する
        ...
    }
}

例 9.5. タイプの利用

Void USRResponder::PrintType(SFYResponderSmpConstRef param) const
{
    switch (param->GetType()) {
        case SFZWindow::CODE_TYPE:
            TRACE("It is a SFZWindow class.");
            break;
        case SFZDialog::CODE_TYPE:
            TRACE("It is a SFZDialog class.");
            break;
        case SFZTextButtonControl::CODE_TYPE:
            TRACE("It is a SFZTextButtonControl class.");
            break;
        default:
            TRACE("It is an unknown class.");
            break;
    }
    return;
}

関連情報 : SFYResponder::SetType | SFYResponder::GetType

9.2.2. ID

ID とは、開発者が自由に設定して利用できる4バイトの値のことです。

SFYResponder::SetID 関数を利用して、0 から 65535 までの範囲内で自由に ID を設定できます。

ID はレスポンダに識別子をつける目的に利用され、ID を用いてレスポンダを検索できます。

[Note] 予約 ID

65536 以上の値の ID は、SophiaFramework UNIVERSE 内部で利用しますので、開発者はこの範囲の ID を設定してはいけません。

[Tip] Tip
異なるレスポンダに同一の ID を設定することもできます。

例 9.6. ID の設定

SFCError USRResponder::MakeButton(Void)
{
    SFZTextButtonControlSmp button;
    SFCError error(SFERR_NO_ERROR);

    if ((button = SFZTextButtonControl::NewInstance(&error)) != null) {
        if ((error = button->SetParent(GetThis())) == SFERR_NO_ERROR) {
            button->SetID(100);
            ...
        }
    }
    return error;
}

例 9.7. ID を用いた検索

SFZTextButtonControlSmp USRResponder::GetButton(Void) const
{
    // ID を用いて子レスポンダを取得できる
    // このようにするとクラス変数を用いて子レスポンダを
    // 管理する必要がなくなる
    return static_pointer_cast<SFZTextButtonControl>(GetChildFront(100));
}

関連情報 : SFYResponder::SetID | SFYResponder::GetID

9.2.3. ルートレスポンダ

ルートレスポンダとは、 木構造をなす複数のレスポンダからなるレスポンダツリーの頂点に位置するレスポンダです。

ルートレスポンダは必ずしもルート(SFZRoot クラス)であるとは限りません。

SFZRoot 以外のレスポンダもレスポンダツリーの頂点にあればルートレスポンダです。

[Caution] 注意

親レスポンダが存在しないレスポンダはルートレスポンダとみなされます。

ウィンドウやコントロールなどすべてのレスポンダは、作成してからレスポンダツリーに接続されるまで一時的にルートレスポンダです。

ルートレスポンダが他のレスポンダと異なる点は、 配信エンジン描画エンジンと結びつけてイベントの配信やレスポンダの描画の起点となるところです。

配信エンジンや描画エンジンに関連付けされていないルートレスポンダを持つレスポンダツリーは、 イベント処理や描画処理を行えません。

SFYApplication クラスでは、 デフォルトのルートレスポンダとして描画エンジンと配信エンジンに関連付けられたルート(SFZRoot クラス)を保持しています。 このため、SFYApplication を継承したアプリケーションクラスを持つアプレット開発では、 明示的にルートレスポンダを設定したり、描画エンジンや配信エンジンをルートレスポンダに接続する必要はありません。

図 9.3. ルートレスポンダと配信エンジン、描画エンジンの関係

ルートレスポンダと配信エンジン、描画エンジンの関係

例 9.8. ルートレスポンダと配信エンジン、描画エンジンの接続

SFCError USRApplication::MakeRoot(Void)
{
    SFYDistributer distributer;  // 配信エンジン
    SFYRenderer renderer;        // 描画エンジン
    SFZRootSmp root;             // ルート
    SFCError error(SFERR_NO_ERROR);

    // 配信エンジンを初期化する
    error = distributer.Initialize();
    if (error == SFERR_NO_ERROR) {
        // 描画エンジンを初期化し、レスポンダ空間を携帯電話の画面全体に設定する
        error = renderer.Initialize(SFXGraphics::GetDeviceRectangle());
        if (error == SFERR_NO_ERROR) {
            // ルートを生成する
            if ((root = SFZRoot::NewInstance(&error)) != null) {
                // ルートに配信エンジンを接続する
                root->SetDistributer(&distributer);
                // ルートに描画エンジンを接続する
                root->SetRenderer(&renderer);
                // ルートの実領域を携帯電話の画面全体(レスポンダ空間)に設定する
                root->SetRealBound(root->GetSuitableBound());
                // ルートの状態を「可視+活性+操作可能+フォーカス」にまとめて設定する
                root->SetState(true, true, true, true);
            }
        }
    }
    return error;
}
[Tip] SFZRoot クラス

SFZRoot はルートレスポンダとして最適化されたレスポンダなので、 ルートレスポンダとして利用するとき SFZRoot を継承して新たなルートを作成する必要はありません。

[Caution] 注意

実際のアプレット開発では、 SFYApplication クラスがルートレスポンダとしてデフォルトでルート(SFZRoot)を保持し、 配信エンジン描画エンジンを接続しているので、 上記のコードをプログラミングする必要はありません。

関連情報 : レスポンダツリー | ルートレスポンダ | レスポンダ空間 | 描画エンジン | 配信エンジン | SFZRoot | SFYDistributer | SFYRenderer | SFYApplication | SFYResponder::SetDistributer | SFYResponder::SetRenderer

9.2.4. 親レスポンダ

親レスポンダとは、自レスポンダを所有し包含している親となるレスポンダのことです。

ウィンドウの中にボタンコントロールが存在する場合、ボタンコントロールの親レスポンダはウィンドウとなります。

親レスポンダが存在しないレスポンダはルートレスポンダと呼ばれ、 レスポンダツリーの頂点に位置します。

GUI コンポーネントとして画面に配置するとき、親レスポンダは子レスポンダよりも背面に配置されます。

図 9.4. 親レスポンダとの包含関係

親レスポンダとの包含関係

例 9.9. 親レスポンダの設定

SFCError USRResponder::SetButtonParent(Void)
{
    SFZWindowSmp window;
    SFZTextButtonControlSmp button;
    SFCError error(SFERR_NO_ERROR);

    ...

    // button の親レスポンダを window に設定する
    if ((error = button->SetParent(window)) == SFERR_NO_ERROR) {

        ...
    }
    return error;
}
[Tip] Tip

レスポンダに親レスポンダを設定するには、SFYResponder::SetParent 関数の引数に親レスポンダを指定します。

また、この操作によりこのレスポンダは親レスポンダが所属しているレスポンダツリーに接続されます。

例 9.10. 親レスポンダのクリア

SFCError USRResponder::ClearButtonParent(Void)
{
    SFZTextButtonControlSmp button;
    SFCError error(SFERR_NO_ERROR);

    ...

    // button の親レスポンダをクリアするには SFYResponderSmp::EmptyInstance() を設定する
    if ((error = button->SetParent(SFYResponderSmp::EmptyInstance())) == SFERR_NO_ERROR) {
        ...
    }
    return error;
}
[Tip] Tip

レスポンダの親レスポンダをクリアするには、SFYResponder::SetParent 関数の引数に SFYResponderSmp::EmptyInstance() を指定します。

また、この操作によりこのレスポンダは元のレスポンダツリーから分離されます。

関連情報 : SFYResponder::SetParent | SFYResponder::GetParent

9.2.5. 子レスポンダ

子レスポンダとは、自レスポンダが所有し包含している子となるレスポンダのことです。

ウィンドウの中にボタンコントロールが存在する場合、ウィンドウの子レスポンダはボタンコントロールとなります。

GUI コンポーネントとして画面に配置するとき、子レスポンダは親レスポンダよりも前面に配置されます。

図 9.5. 子レスポンダとの包含関係

子レスポンダとの包含関係

例 9.11. 子レスポンダの検索

SFYResponderSmp USRResponder::SearchChild(SInt32 index) const
{
    // 可視な子レスポンダの中で前面から index 番目の
    // 子レスポンダを検索する
    // この他にも数多くの検索方法を利用できる
    return GetChildForward(index, true, false, false, false);
}

関連情報 1 : SFYResponder::GetChildBack | SFYResponder::GetChildFront | SFYResponder::GetChildBackward | SFYResponder::GetChildForward | SFYResponder::GetChildCount

関連情報 2 : SFYApplication::GetChildBack | SFYApplication::GetChildFront | SFYApplication::GetChildBackward | SFYApplication::GetChildForward | SFYApplication::GetChildCount

9.2.6. 姉妹レスポンダ

姉妹レスポンダとは、自レスポンダと同じ親レスポンダを持つ姉妹となるレスポンダのことです。

GUI コンポーネントとして画面に配置するとき、姉レスポンダは妹レスポンダよりも前面に配置されます。

図 9.6. 姉妹レスポンダとの包含関係

姉妹レスポンダとの包含関係

例 9.12. 姉妹レスポンダの検索

SFYResponderSmp USRResponder::SearchNextSister(Void) const
{
    SFYResponderSmp parent;
    SFYResponderSmp result;

    // 自レスポンダと同じ親レスポンダを持つすべての姉妹レスポンダの中で
    // 自レスポンダの次の姉妹レスポンダを検索する
    if ((parent = GetParent()) != null) {
        if ((index = GetNthBackward(false, false, false, false)) > 0) {
            result = parent->GetChildBackward(index - 1, false, false, false, false);
        }
    }
    return result;
}

関連情報 : SFYResponder::SetParent | SFYResponder::GetParent | SFYResponder::GetChildBack | SFYResponder::GetChildFront | SFYResponder::GetChildBackward | SFYResponder::GetChildForward | SFYResponder::GetChildCount | SFYResponder::GetNthBackward | SFYResponder::GetNthForward | SFYResponder::ToNthBackward | SFYResponder::ToNthForward | SFYResponder::IsNthBackward | SFYResponder::IsNthForward | SFYResponder::IsBack | SFYResponder::IsFront | SFYResponder::ToBack | SFYResponder::ToFront

9.2.7. 実領域

実領域とは、 親レスポンダのローカル領域にレスポンダの可視領域を配置するための矩形領域のことです。

実領域は、親レスポンダのローカル領域の左上端を原点(0, 0)とする相対座標系の矩形領域で表されます。

レスポンダの実領域を親レスポンダのローカル領域内に配置するための関数として SFYResponder::SetRealBound 関数が用意されています。

図 9.7. 実領域の位置関係


実領域の位置関係

※実領域は、親レスポンダ領域(ローカル領域)の左上端を原点(0,0)とする座標系の矩形(SFXRectangle)として表されます。

例 9.13. 最適な大きさを取得し実領域を設定

Void USRResponder::SetButtonBound(Void)
{
    SFZTextButtonControlSmp button;

    ...
    button->SetRealBound(button->GetSuitableBound().SetOrigin(10, 10));
    ...
    return;
}
[Caution] 実領域を縮小したときの注意

仮想領域が実領域と一致しているとき、 SFYResponder::SetRealBound 関数を利用して実領域を狭くすると、 仮想領域はそのままなので実領域よりも広くなります。

実領域よりも広い仮想領域を持つ必要のないレスポンダでは、 SFYWidget::HandleBoundReal 関数をオーバーライドして仮想領域を実領域に一致させることを推奨します。

SFYControl を継承するコントロール系クラスでは、 SFYControl::HandleBoundReal 関数をオーバーライドしない限り、 仮想領域は常に実領域と一致します。

関連情報 : SFYResponder::SetVirtualBound | SFYControl::HandleBoundReal | SFYControl

関連情報 : SFYResponder::SetRealBound | SFYResponder::GetRealBound

9.2.8. 仮想領域

仮想領域とは、 このレスポンダの実領域の左上端を原点(0, 0)とする相対座標系で表したレスポンダ全体の矩形領域のことです。大きさはローカル領域と同じです。

仮想領域は、実領域よりも大きなレスポンダをスクロールして表示するときに利用されます(実領域はレスポンダの可視領域です)。

図 9.8. 仮想領域と実領域の位置関係


仮想領域と実領域の位置関係

※仮想領域は、実領域の左上端を原点(0,0)とする座標系の矩形(SFXRectangle)として表されます。

レスポンダの仮想領域を設定するための関数として SFYResponder::SetVirtualBound 関数が用意されています。

仮想領域は、実領域を含むように設定する必要があります。 仮想領域を設定しない場合、仮想領域は実領域に等しく、レスポンダの全領域が可視領域となります。

図 9.9. 実領域と仮想領域の配置関係


実領域と仮想領域の配置関係

※実領域は必ず仮想領域内に配置されなければいけません。

例 9.14. 仮想領域のスクロール

Void USRResponder::ScrollVirtualBound(Void)
{
    // 現在の仮想領域を取得し、原点の Y 座標を 10 ピクセル移動させ設定する
    // このようにすると仮想領域は実領域に対して上に移動することになる
    SetVirtualBound(SFXRectangle(GetVirtualBound()).SubY(10));
    return;
}
[Caution] 仮想領域を拡大したときの再描画

仮想領域を拡大すると、ローカル領域に対する実領域の相対的な位置関係が変化することがあります。

拡大前と同じ内容を実領域に表示させるためには、 ローカル領域に対する実領域の相対的な位置関係の変化を描画処理に反映させる必要があります。

コントロール系レスポンダでは、 SFYWidget::HandleBoundVirtual 関数をオーバーライドして仮想領域を実領域に一致させることを推奨します。

関連情報 : SFYResponder::SetVirtualBound | SFYResponder::SetRealBound | SFYWidget::HandleBoundVirtual | SFYControl::HandleBoundReal

関連情報 : SFYResponder::SetVirtualBound | SFYResponder::GetVirtualBound

9.2.9. ローカル領域

ローカル領域とは、 レスポンダの左上端を原点(0,0)とする座標系で表したレスポンダ全体の矩形領域のことです。大きさは仮想領域と同じです。

レスポンダの描画処理は、 描画ハンドラ内で SFYResponder::GetLocalBound 関数を利用して取得したローカル領域に対して行います。

図 9.10. ローカル領域の位置関係


ローカル領域の位置関係

※ローカル領域は、レスポンダ領域の左上端を原点(0,0)とする座標系の矩形(SFXRectangle)として表されます。

例 9.15. ローカル領域を用いた描画

XANDLER_IMPLEMENT_VOIDRENDER(USRResponder, OnRenderRequest, invoker, reason, graphics)
{
    // ローカル領域全体を白色で塗り潰す
    graphics->FillRectangle(GetLocalBound(), SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00));
    return;
}

関連情報 : SFYResponder::GetLocalBound

9.2.10. グローバル領域

グローバル領域とは、 実領域を画面の左上端を原点(0, 0)とする絶対座標系で表した矩形領域のことです。

グローバル領域は、 BREW 標準コントロールを配置する際に必要となる絶対座標系で表したレスポンダの実領域として利用します。

図 9.11. グローバル領域の位置関係


グローバル領域の位置関係

※グローバル領域は、画面の左上端を原点(0,0)とする座標系の矩形(SFXRectangle)として表されます。

関連情報 : SFYResponder::GetGlobalBound

9.2.11. 属性

レスポンダの属性には、透過/非透過(デフォルトは非透過)を表す透過属性があります。

レスポンダの属性が非透過の場合、 レスポンダの背景は SFYWidget::SetBackgroundColor 関数で設定された色(デフォルトは白色)で塗り潰されます。

図 9.12. 透過属性の例

透過属性の例

例 9.16. 透過属性の設定

Void USRResponder::SetTransparent(Void)
{
    SetPropertyTransparent(true);
    return;
}

関連情報 : SFYResponder::SetProperty | SFYWidget::SetBackgroundColor | SFYResponder::SetPropertyTransparent | SFYResponder::GetPropertyTransparent

9.2.12. 状態

レスポンダには、以下のような順序で優先順位が設定された5つの状態があります。

  1. 有効状態
  2. 可視状態
  3. 活性状態
  4. 操作可能状態
  5. フォーカス状態

表 9.2. レスポンダの状態

優先度 名称 解説
1 有効状態 有効 / 無効 レスポンダが初期化されているかどうかを表します。初期化はレスポンダ生成時に自動的に行われます。 SFYResponder::Terminate 関数を呼び出すと、レスポンダの有効状態は「無効」になります。
2 可視状態 可視 / 不可視 レスポンダが見えるかどうかを表します。 親レスポンダの実領域の外側にあるレスポンダや姉妹レスポンダに覆い隠されて描画されないレスポンダは、 不可視に設定しておくと描画速度が向上します。
3 活性状態 活性 / 不活性 レスポンダが操作対象になりえるかどうかの見た目を表します。 操作対象になりえないレスポンダはラベルの色が薄くなったり平面的なデザインになったります。 活性状態は見た目の状態のみを表し、操作可能状態とは区別されます。
4 操作可能状態 操作可能 / 操作不可能 レスポンダが操作可能かどうかを表します。 活性状態とは違い、操作可能でも操作不可能でも見た目に違いはありません。 操作不可能なレスポンダはフォーカスされることはありません。
5 フォーカス状態 フォーカス / 非フォーカス レスポンダが操作対象になっているかどうかを表します。 同じ姉妹レスポンダの中では、最高1つのレスポンダにしかフォーカスを設定できません。 あるレスポンダにフォーカスを設定すると、 それまでフォーカスされていた同じ姉妹のレスポンダはフォーカスされなくなります。

図 9.13. 5つの状態の例

5つの状態の例

例 9.17. 状態の設定

Void USRResponder::SetState(Void)
{
    // 可視+活性+操作可能+フォーカスにまとめて設定する
    SetState(true, true, true, true);

    // 可視状態を不可視に設定する
    // このときフォーカス状態は自動的に非フォーカスになる
    SetStateVisible(false);

    // 再度可視に設定すると、自動的にフォーカスされた状態に戻る
    SetStateVisible(true);

    // 下記のように明示的にフォーカスに設定する必要はない
    // SetStateFocus(true); ← このコードは不要

    return;
}

可視状態、活性状態、操作可能状態、フォーカス状態の各状態には物理的状態と視覚的状態の2種類の状態が定義されています。 有効状態には物理的状態しか定義されていません。

レスポンダの状態を取得するための GetStateVisible/Active/Enable/Focus 関数では、 引数の指定により物理的状態と視覚的状態の両方を取得できます。

[Note] 物理的状態と視覚的状態の詳細

物理的状態とは、レスポンダが持つ状態フラグに設定された true または false の値です。 true は「物理的 ON」であること、false は「物理的 OFF」であることを表します。

視覚的状態とは、 自レスポンダの物理的状態と優先順位が上位の視覚的状態、 および親レスポンダの視覚的状態を総合した状態を表します。

視覚的状態は、 下記の3つの条件をすべて満足したときに限り「視覚的 ON」であり、それ以外は「視覚的 OFF」です。

  1. 自レスポンダの状態が「物理的 ON」である
  2. 親レスポンダの状態が「視覚的 ON」である(ただし自レスポンダがルートレスポンダである場合を除く)
  3. 自レスポンダの優先順位が上位の状態が「視覚的 ON」である(可視状態については有効状態が「物理的 ON」である)

レスポンダは、「視覚的 ON」のときにその状態が ON である振る舞いを行います。 「物理的 ON」であっても「視覚的 OFF」であれば、その状態が ON である振る舞いは行いません。

たとえば、可視状態の場合、 「視覚的 ON」のウィンドウは見えますが、「物理的ON」でも「視覚的 OFF」であればウィンドウは見えません。

画面上にAというウィンドウが表示されていて目視できる状態にあるとします。 このとき、ウィンドウの可視状態は「視覚的 ON」です。

ウィンドウには目視できるボタンがあれば、 ボタンの可視状態も「視覚的 ON」です。

ウィンドウの可視状態を「物理的 OFF」にすると、自動的に「視覚的 OFF」になります。 子であるボタンの可視状態は自動的に「視覚的 OFF」になりますが、「物理的 ON」のままです。

つまり、親であるウィンドウを見えなくするだけで自動的に子であるボタンも画面に表示されなくなります。

ボタンがフォーカスされていて画面に表示されているとします。

このとき、ボタンのフォーカス状態と可視状態は「視覚的 ON」です。

このとき、フォーカス状態よりも優先順位の高い可視状態を「物理的 OFF」にすると、自動的に「視覚的 OFF」になります。 フォーカス状態は「物理的 ON」のままですが、自動的に「視覚的 OFF」になり、ボタンはフォーカスされなくなります。

[Note] 状態イベントの処理

視覚的状態が変化すると、 状態イベントが発生します。

状態イベント専用ハンドラを登録することで、 視覚的状態が変化したときの処理を行えます。

関連情報 1 : SFYResponder::Initialize | SFYResponder::Terminate

関連情報 2 : SFYResponder::SetState

関連情報 3 : SFYResponder::SetStateVisible | SFYResponder::GetStateVisible | SFYResponder::SetStateActive | SFYResponder::GetStateActive | SFYResponder::SetStateEnable | SFYResponder::GetStateEnable | SFYResponder::SetStateFocus | SFYResponder::GetStateFocus

9.2.13. イベント

イベント(SFXEvent)は、 イベントタイプと2つのパラメータ(P16 パラメータと P32 パラメータ)から構成されます。

イベントを処理するハンドラは、 RegisterHandler() 関数を利用してレスポンダに登録します。

イベントには、BREW SDK で定義される BREW 定義イベント、 SophiaFramework UNIVERSE 独自のレスポンダ定義イベント、 ユーザー独自のユーザー定義イベントの 3 種類があります。

BREW 定義イベントのイベントタイプ名は、BREW SDK で定義されるイベントタイプ名の先頭に SF 接頭語が付加された名前になります。

たとえば、SFEVT_KEY イベント(キーイベント)は BREW 定義イベントです。

一方、レスポンダ定義イベントのイベントタイプ名は、 SFEVT_RESPONDER_ 接頭語が付加された名前になります。

たとえば、SFEVT_RESPONDER_RENDER イベント(描画イベント)は レスポンダ定義イベントです。

また、イベントの配信方法からイベントは配信型イベントと、 コールバック型イベントの 2 種類に分類されます。

配信型イベントは Distribute() 関数を利用して配信します。 配信型イベントはトレーサの配信規則によりレスポンダに配信され、 ハンドラが呼び出されます。 BREW 定義イベントは配信型イベントです。

コールバック型イベントは InvokeForward() または InvokeBackward() 関数を呼び出すことでレスポンダに配信され、 ハンドラが呼び出されます。 レスポンダ定義イベントはコールバック型イベントです。

[Caution] ユーザー定義イベント

ユーザー定義イベントとは、SFEVT_USER_CLASS_BEGIN(0x8000) から SFEVT_USER_CLASS_END(0xFFFE) の範囲でユーザーが自由に定義できるユーザー独自のイベントのことです。

ユーザー定義イベントについてはデフォルトの配信規則がトレーサに設定されていませんので、 配信型イベントとしてハンドラを登録してもイベントを受信できません。

ユーザー定義イベントを配信型イベントとして受信するには、配信規則をトレーサに登録する必要があります。

関連情報 : イベント一覧 | イベント処理 | イベントドリブン | BREW 定義イベント | レスポンダ定義イベント | 配信型 | トレーサ | コールバック型 | SFXEvent | SFXEventRange | SFCEventEnum | SFYResponder::Distribute | SFYResponder::InvokeBackward | SFYResponder::InvokeForward | SFYResponder::RegisterHandler | SFYApplication::Distribute | SFYApplication::InvokeBackward | SFYApplication::InvokeForward | SFYApplication::RegisterHandler

9.2.14. 配信エンジン

配信エンジンとは、 トレーサに登録された規則に従ってイベントをレスポンダに配信し、 ハンドラを呼び出すためのアルゴリズム(SFYDistributer クラス)のことです。

配信エンジンは、レスポンダツリー毎に1つ必要であり、 ルートレスポンダと結び付けます。

イベントループの最初のタイミングで自動的に呼び出される SFYResponder::Distribute 関数の中で内部的に起動されます。

[Tip] 配信型イベント

Distribute() 関数を利用して配信するイベントのことを配信型イベントと定義します。 BREW 定義イベントは配信型イベントです。

関連情報 : SFYDistributer | レスポンダツリー | ルートレスポンダ | イベントループ | 配信型 | イベント | BREW 定義イベント | トレーサ | ハンドラ | SFYResponder::Distribute | SFYApplication::Distribute | SFZRoot | SFYResponder::GetDistributer | SFYResponder::SetDistributer | SFXEvent | SFXEventRange

9.2.15. 描画エンジン

描画エンジンとは、 レスポンダツリーとして構成された複数のレスポンダを自動的に描画するためのアルゴリズム(SFYRenderer クラス)のことです。

描画エンジンは、レスポンダツリー毎に1つ必要であり、 ルートレスポンダと結び付けます。

イベントループの最後のタイミングで自動的に呼び出される SFYResponder::Render 関数の中で内部的に起動されます。

コールバックなどイベントループ外の処理で再描画するには、 明示的に SFYResponder::Render 関数を呼び出して描画エンジンを起動する必要があります。

関連情報 : SFYRenderer | レスポンダツリー | ルートレスポンダ | イベントループ | 描画処理 | SFYResponder::Render | SFYApplication::Render | SFYResponder::Invalidate | SFYApplication::Invalidate | SFZRoot | SFYResponder::GetRenderer | SFYResponder::SetRenderer | SFXEvent | SFXEventRange

9.2.16. トレーサ

トレーサは、 配信型イベントの配信規則のことで、 SFYTracer クラスが管理します。

トレーサに登録する各配信規則には、以下の3つの要素があります(詳細情報 : 標準トレーサ)。

  1. 配信条件.イベントを配信するレスポンダの状態を指定します。

  2. 処理順序.ハンドラを呼び出す順序を指定します。

  3. 重複条件.イベントを重複して処理するかどうかを指定します。

同一のイベントに対して複数の配信規則をトレーサに登録した場合、最後に登録した配信規則に基づいてイベントは配信されます。

[Caution] トレーサに設定可能なイベントの種類

トレーサの設定は、配信型イベントについて行います。 コールバック型イベントの配信規則はトレーサに登録してはいけません。

[Tip] 配信型イベント

Distribute() 関数を利用して配信するイベントのことを配信型イベントと定義します。 BREW 定義イベントは配信型イベントです。

[Tip] コールバック型イベント

InvokeForward() または InvokeBackward() 関数を利用して送信するイベントのことをコールバック型イベントと定義します。 レスポンダ定義イベントはコールバック型イベントです。

関連情報 : 標準トレーサ | イベント

例 9.18. トレーサへの配信規則の登録

SFCError USRResponder::MakeTracer(Void)
{

    // AVK_SOFT1 から AVK_SOFT4 までのキーイベントについて
    // 『処理順序:前面から背面、配信条件:すべての状態、重複条件:なし』
    // という配信規則をトレーサに登録する
    return RegisterTracer(
        SFXEventRange(SFEVT_KEY, SFEVT_KEY, AVK_SOFT1, AVK_SOFT4),
        SFYTracer::ORDER_FORWARD, SFYTracer::STATE_ALL, false
    );
}
[Tip] Tip
トレーサの配信規則は、RegisterTracer() 関数を利用して登録します。

関連情報 : SFYTracer | SFXEvent | SFXEventRange | SFYResponder::Distribute | SFYResponder::RegisterTracer | SFYResponder::UnregisterTracer | SFYResponder::ClearTracer | SFYApplication::RegisterTracer | SFYApplication::UnregisterTracer | SFYApplication::ClearTracer

9.2.17. ハンドラ

ハンドラとは、イベントを処理するハンドラ関数のことで、SFYHandler クラスが管理します。

ハンドラ関数は、RegisterHandler() 関数を利用してイベントと関連付けてレスポンダに登録します。 同一のイベントに対して複数のハンドラ関数を登録することも可能です。

ハンドラ関数は、登録の順あるいは登録の逆順で呼び出せます。 ハンドラ関数がイベントを処理したとき、そこで終了することも、ハンドラが無くなるまでハンドラの呼び出しを継続することも設定により可能です。

例 9.19. ハンドラの登録

SFCError USRResponder::MakeHandler(Void)
{
    return RegisterHandler(
        SFXEventRange(SFEVT_KEY, SFEVT_KEY, SFP16_BEGIN, SFP16_END),
        XANDLER_INTERNAL(OnKey)
    );
}
[Tip] Tip
ハンドラは、RegisterHandler() 関数を利用して登録します。

関連情報 : イベント | コールバック型 | 配信型 | SFYHandler | SFXEvent | SFXEventRange | SFYResponder::RegisterHandler | SFYResponder::UnregisterHandler | SFYResponder::ClearHandler | SFYApplication::RegisterHandler | SFYApplication::UnregisterHandler | SFYApplication::ClearHandler

9.2.18. 配信型

配信型とは、 配信エンジンを利用してハンドラを呼び出す方法のことです。

具体的には、 配信エンジンはトレーサに登録された規則を参照してイベントを然るべきレスポンダに配信し、 ハンドラを呼び出します。

[Tip] Tip

BREW 定義イベントは配信型で送信されます。

[Caution] 注意

配信型で送信されるイベントは、トレーサに登録する規則を利用して送信先のレスポンダの子レスポンダにも送信することが可能です。

関連情報 : 配信エンジン | イベント | BREW 定義イベント | ハンドラ | ハンドラリスト | トレーサ | SFYResponder::Distribute | SFYApplication::Distribute | コールバック型

9.2.19. コールバック型

コールバック型とは、InvokeForward() または InvokeBackward() 関数を利用してイベントを送信し、 ハンドラを呼び出す方法のことです。

ハンドラリスト内のハンドラを最前面から呼び出す場合は InvokeForward() 関数、 最背面から呼び出す場合は InvokeBackward() 関数を利用します。

InvokeForward() / InvokeBackward() 関数は、イベントを重複して処理するかどうかを表す重複条件を引数として指定する必要があります。

[Tip] Tip

レスポンダ定義イベントはコールバック型で送信されます。

[Caution] 注意

コールバック型で送信されるイベントは、送信先のレスポンダ内だけで処理されます(子レスポンダには配信されません)。

関連情報 : イベント | レスポンダ定義イベント | ハンドラ | ハンドラリスト | SFYResponder::InvokeForward | SFYResponder::InvokeBackward | SFYApplication::InvokeForward | SFYApplication::InvokeBackward | 配信型

9.2.20. イベントループ

イベントループとは、 BREW 環境で発生した BREW 定義イベントが、 トレーサの規則に従ってレスポンダに配信され、 ハンドラが呼び出される工程の繰り返しのことです。

詳しくは、イベント処理をご覧ください。

9.2.21. トレーサリスト

トレーサリストとは、SFYTracer クラスが管理するトレーサの配信規則のリストのことです。 レスポンダのインスタンスに付き1つのトレーサリストが存在します。

トレーサリストはスタック型で管理されます。 新しく登録した配信規則はトレーサリストの先頭に追加され、 配信規則の削除はトレーサリストの先頭から検索され、条件に一致したものが削除されます(1つ削除すれば処理は終了します)。

関連情報 : SFYTracer | トレーサ

9.2.22. ハンドラリスト

ハンドラリストとは、SFYHandler クラスが管理しているハンドラ(ハンドラ関数)のリストのことです。 レスポンダのインスタンスに付き1つのハンドラリストが存在します。

ハンドラリストはスタック型で管理されます(スタックの先頭が最前面、底が最背面)。 新しく登録したハンドラ関数はハンドラリストの先頭(最前面)に追加され、 ハンドラ関数の削除はハンドラリストの先頭(最前面)から検索され、条件に一致したものが削除されます(1つ削除すれば処理は終了します)。

ハンドラ関数を呼び出すときのリストの辿り方は、 ハンドラリストの先頭(最前面)から底(最背面)と、底(最背面)から先頭(最前面)の2通りの方法があります。

関連情報 : SFYHandler | ハンドラ

9.2.23. リファレンス

リファレンスとは、レスポンダに設定できる4バイトのリファレンス値(VoidPtr 型)のことです。

例 9.20. テキストボタンコントロールのラベル付け

SFZTextButtonControlSmp _button;
SInt32 i;

// 10 個のテキストボタンコントロールを作成し番号(リファレンス値)を設定する
for (i = 0; i < 10; ++i) {
    if ((_button = SFZTextButtonControl::NewInstance(&error)) != null) {
        error = _button->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {
            // テキストボタンコントロール識別用番号を設定する
            _button->SetReference(reinterpret_cast<VoidPtr>(i));
        }
    }
}

...

// テキストボタンコントロール識別用番号を取得する
SInt32 number = reinterpret_cast<SInt32>(_button->GetReference());

関連情報 : SFYResponder::GetReference | SFYResponder::SetReference