前のページ次のページ上に戻るホーム SophiaFramework UNIVERSE 5.2

9.8. ルート(基礎編)

ルート(SFZRoot)は、 レスポンダツリーの頂点(ルートレスポンダ)に配置されるように設計されたレスポンダです。

配信エンジン(SFYDistributer)と 描画エンジン(SFYRenderer)をルートに関連付けると、 ルートはイベントをレスポンダツリー上のレスポンダに送信したり、レスポンダツリー上のレスポンダを描画することが可能になります。

[Tip] Tip

SFYApplication クラスが保持するデフォルトのルートは配信エンジンと描画エンジンが関連付けられているので、 一般的なアプリ開発ではこれらのエンジンをルートに関連付ける必要はありません。

1 つのアプリケーションクラスが複数個のルートを保持することも可能ですが、 通常デフォルトのルートだけで十分です。

表 9.7. 具象ルートの種類

クラス名 解説
SFZRoot ウィンドウ、 ダイアログやメニューを配置する汎用ルートです。
[Important] 重要

すべての具象ルートにおいて、 SFYResponder::SetDistributer 関数、 SFYResponder::SetRenderer 関数、 SFYResponder::SetState 関数、 SFYResponder::SetRealBound 関数の呼び出しは必須です。

その他の関数の呼び出しは省略可能です。

9.8.1. ウィンドウ、ダイアログやメニューを配置する汎用ルート[SFZRoot]

SFZRoot は、 ウィンドウダイアログメニューを配置するための汎用的なルートとして機能します。

SFYApplication クラスを継承するアプリケーションクラスを使用するアプリ開発では、 SFYApplication クラスがデフォルトのルート(SFZRoot)を保持しているため、 ルートを作成する必要はありません。

SFCApplication を直接継承するアプリケーションクラスで GUI フレームワークを利用する場合や、 2 つ以上のレスポンダツリーを使用する場合は、 ルートを作成する必要があります。

図 9.29. 動作例

動作例

以下は、 SFCApplication クラスを継承して、 GUI フレームワークを利用するアプリケーションクラスを実装するためのコードです。 SFYApplication クラスは下記と同等の内容で実装されています。

例 9.45. 宣言

SFMTYPEDEFCLASS(USRApplication)
class USRApplication: public SFCApplication {
    SFMSEALCOPY(USRApplication)
private:
    SFZRootSmp       _root;         // ルート
    SFYDistributer   _distributer;  // 配信エンジン
    SFYRenderer      _renderer;     // 描画エンジン 
    SFXBaseEditorPtr _editor;       // テキスト入力コントロールエディタ

    // ...(省略)...

private:
    explicit USRApplication(Void) static_throws;    
    virtual ~USRApplication(Void);
    virtual Bool HandleEvent(SFXEventConstRef event);
    virtual Bool HandleRender(SFXEventConstRef event);
    SFCError Make(Void);
    Bool Do(SFXEventConstRef event);
    Void Dispose(Void);
};

例 9.46. 実装 1

SFCError USRApplication::Make(Void)
{
    SFCError error(SFERR_NO_ERROR);

    // 初期化処理

    // テキスト入力コントロールエディタを作成する
    if ((_editor = ::new SFXEditor) != null) {

        // 配信エンジンを初期化する
        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);

                    // ルートの実領域を設定する
                    // ※1. 親レスポンダが存在しないルートはレスポンダ空間内に実領域を設定する
                    // ※2. _root->GetSuitableBound() はレスポンダ空間(=「携帯電話の画面領域」)を返す
                    // ※3. ルートの実領域は携帯電話の画面領域に設定される
                    _root->SetRealBound(_root->GetSuitableBound());

                    // ルートの状態を「可視+活性+操作可能+フォーカス」にまとめて設定する
                    _root->SetState(true, true, true, true);
                }
            }
        }
    } else {

        error = SFERR_NO_MEMORY;
    }

    return error;
}

Bool USRApplication::Do(SFXEventConstRef event)
{
    SFCError error;
    Bool result(false);

    // レスポンダツリーにイベントを配信する
    // イベントを最初に受信するのはルートに関連付けられた SFYDistributer インスタンス
    // その後、トレーサの配信規則に基づいてルートを頂点とするレスポンダツリー上のレスポンダにイベントは配信される
    error = _root->Distribute(event, &result);
    if (error == SFERR_NO_ERROR) {

        if (result) {

            if (IsRenderable()) {

                // レスポンダツリーを描画する
                error = _root->Render();
            }
        }
    }
    if (error != SFERR_NO_ERROR) {

        // イベント配信の失敗や描画の失敗など、
        // 致命的なエラーが発生したときの処理を記述する
    }

    return result;
}

Void USRApplication::Dispose(Void)
{
    // 終了処理(必ず下記の順序で行う)

    // テキスト入力コントロールエディタを破棄する
    ::delete _editor;

    // レスポンダツリーを解放する
    _root.Release();

    // 描画エンジンを終了する
    _renderer.Terminate();

    // 配信エンジンを終了する
    _distributer.Terminate();

    return;
}
[Note] レスポンダ空間

レスポンダ空間とは、 描画エンジンに関連付けられた、 レスポンダツリーを描画する画面上の矩形領域のことです。

レスポンダ空間は、描画エンジンを初期化する SFYRenderer::Initialize 関数を使用して設定します。 この初期化の後、レスポンダ空間は動的に拡大したり、縮小することはできません。

デフォルトでは、レスポンダ空間は端末の全画面の矩形領域に設定されます。

上記コードの USRApplication::Make 関数、USRApplication::Do 関数、USRApplication::Dispose 関数は、 以下のようにコンストラクタ、イベントハンドラ、デストラクタからそれぞれ呼び出されます。

例 9.47. 実装 2

// コンストラクタ
USRApplication::USRApplication(Void)
{
    if (static_try()) {
 
        static_throw(Make());
 
        // その他の初期化処理を記述する
 
    }
}

// イベントハンドラ
Bool USRApplication::HandleEvent(SFXEventConstRef event)
{
    SFCError    error;
    Bool        result(false);

    result = Do(event);
 
    // その他の処理を記述する
 
    return result;
}

// 全画面描画ハンドラ
Bool USRApplication::HandleRender(SFXEventConstRef event)
{
    SFCError    error;
    Bool        result(false);
 
    if (IsRenderable()) {

        if ((error = _root->Render(true)) == SFERR_NO_ERROR) {

            result = true;
        }
        else {

            // エラーが発生したとき

	    // ...(省略)...
        }
    }

    return result;
}

// デストラクタ
USRApplication::~USRApplication(Void)
{
    Dispose();
 
    // その他の終了処理を記述する

}