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

9.18. フレーム

SFYFrame を継承するレスポンダを『フレーム』と呼びます。

SFYResponder::SetFrame 関数を使用してフレームをレスポンダに装着することにより、 枠線やタイトルなどの枠組みをレスポンダに表示することが可能になります。

フレーム装着の対象となるレスポンダは、 以下の 3 種類です。

  1. SFZWindow を継承するウィンドウ
  2. SFZDialog を継承するダイアログ
  3. SFYMenu を継承するメニュー

フレームには、以下の 3 種類があります。

  1. プレーンフレーム: 影だけの枠
  2. フラットフレーム: 影付きの平面的な枠
  3. ベベルフレーム: 影付きの立体的な枠
[Note] 注意

フレームのヘッダー部分にタイトルを付けることも可能です。

図 9.47. 動作例(各種フレーム)


各種フレーム

上段(左から): プレーンフレーム[SFZPlainFrame]、 フラットフレーム[SFZFlatFrame]、 ベベルフレーム[SFZBevelFrame]

下段(左から): タイトル付きプレーンフレーム[SFZTitlePlainFrame]、 タイトル付きフラットフレーム[SFZTitleFlatFrame]、 タイトル付きベベルフレーム[SFZTitleBevelFrame]

図 9.48. タイトル付きベベルフレーム[SFZTitleBevelFrame]


タイトル付きベベルフレーム[SFZTitleBevelFrame]

SFYResponder::SetFrame 関数を使用してタイトル付きベベルフレームをレスポンダに装着することで、 立体的なタイトル枠付きレスポンダを実現できます。

図 9.49. タイトル付きベベルフレーム拡大図[SFZTitleBevelFrame]


タイトル付きベベルフレーム拡大図[SFZTitleBevelFrame]

■ フレームの使い方

  1. NewInstance 関数を呼び出して、 フレームのインスタンスを作成します。
  2. SFYResponder::SetState 関数を呼び出して、 フレームの可視、活性、操作可能、フォーカスの 4 つの状態のフラグ値をすべて true に設定します。
  3. SFYResponder::SetFrame 関数を呼び出して、 フレームをレスポンダに装着します。
    [Note] 注意
    このとき、レスポンダに装着したフレームを『アタッチメントフレーム』、 フレームが装着されたレスポンダを『コンテントレスポンダ』と呼びます。
  4. SFYResponder::SetRealBound 関数を呼び出して、 コンテントレスポンダまたはアタッチメントフレーム、 いずれか一方の実領域を設定します。
    [Tip] Tip

    もう片一方の実領域は、 アタッチメントフレームのフレーム余白領域のサイズから計算して自動的に設定されます。

    SFYResponder::SetFrame 関数の内部では、 コンテントレスポンダの実領域をフレーム余白領域のサイズだけ拡大した領域をアタッチメントフレームの実領域に設定する処理も行います。 そのため、コンテントレスポンダの実領域の設定は、 SFYResponder::SetFrame 関数の呼び出しよりも前に行うことも可能です。

  5. SFYResponder::ToFront 関数を呼び出して、 コンテントレスポンダを最前面に移動します。 このとき、アタッチメントフレームも一緒に自動的に最前面に移動します。
[Tip] Tip
同一フレームを様々なレスポンダに装着するために、 装着対象レスポンダに関わるプロパティをフレームに持たせないことを推奨します。
[Note] 注意
コンテントレスポンダとアタッチメントフレームについての詳細は、 こちらを参照してください。

■ フレームクラスの種類

すべてのフレームクラスは SFYFrame を継承し、 フレーム用余白領域のサイズを計算したり、 枠線やタイトルなどを設定したり、 自分自身を描画する機能を提供します。

具象フレームクラスはアプリ開発ですぐに使うことができる部品であり、 抽象フレームクラスはカスタマイズされたユーザー定義フレームクラスを作成するための起点(基底クラス)となります。

表 9.20. 具象フレームクラスの種類

クラス名 解説
SFZPlainFrame プレーンフレームです。
SFZFlatFrame フラットフレームです。
SFZBevelFrame ベベルフレームです。
SFZTitlePlainFrame タイトル付きプレーンフレームです。
SFZTitleFlatFrame タイトル付きフラットフレームです。
SFZTitleBevelFrame タイトル付きベベルフレームです。
[Important] 重要

具象フレームクラスでは、 SFYResponder::SetState 関数の呼び出しは必須です。 通常、可視、活性、操作可能、フォーカスの状態は、 すべて "true" に設定します。

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

フレームは、SFYResponder::SetFrame 関数を使用してレスポンダに装着することを推奨します。

コンテントレスポンダの SFYResponder::SetRealBound 関数を呼び出すと、 アタッチメントフレームの実領域は自動的に設定されます。 逆に、アタッチメントフレームの SFYResponder::SetRealBound 関数を呼び出すと、 コンテントレスポンダの実領域が自動的に設定されます。

[Caution] 注意

アタッチメントフレームでは、 SFYResponder::SetParent 関数を呼び出せません。 また、SFYResponder::SetFrame 関数の引数には親レスポンダを持たないフレームを指定します。

表 9.21. 抽象フレームクラスの種類

クラス名 解説
SFYFrame フレームの抽象クラスです。
SFYPlainFrame プレーンフレームの抽象クラスです。
SFYFlatFrame フラットフレームの抽象クラスです。
SFYBevelFrame ベベルフレームの抽象クラスです。

例 9.86. 宣言

SFMTYPEDEFCLASS(USRApplication)
class USRApplication: public SFYApplication {
    SFMSEALCOPY(USRApplication)
private:

    SFZTitleBevelFrameSmp _frame;
    SFZMessageDialogSmp _dialog;

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

private:
    SFCError MakeFrame(Void);
    SFCError MakeDialog(Void);


    // ダイアログ選択結果イベントを受信するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.87. 実装

// フレームの作成
SFCError USRApplication::MakeFrame(Void)
{
    SFCError error(SFERR_NO_ERROR);

    // タイトル付きベベルフレームの生成(フレームの種類によってデザインが異なる)
    // 他のフレームについても同様にしてウィンドウやダイアログに枠組みを設定できる
    if ((_frame = SFZTitleBevelFrame::NewInstance(&error)) != null) {

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

        // その他フレームの設定
        // ...(省略)...
    }
    if ( error == SFERR_NO_ERROR) {

        // フレーム付きダイアログを作成し表示する
        error = MakeDialog();
    }

    return error;
}

// フレーム付きダイアログの作成と表示
SFCError USRApplication::MakeDialog(Void)
{
    SFXRectangle rectangle;
    SFXMargin margin;
    SFCError error(SFERR_NO_ERROR);

    // ダイアログの生成
    if ((_dialog = SFZMessageDialog::NewInstance(&error)) != null) {

        // ダイアログの親レスポンダをルートに設定する
        error = _dialog->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // ダイアログにフレームを装着する
            error = _dialog->SetFrame(_frame);
            if (error == SFERR_NO_ERROR) {

                // ダイアログ選択結果イベントを受信するハンドラを登録する
                error = _dialog->RegisterHandler(
                               SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                               XANDLER_INTERNAL(OnResult)
                );
                if (error == SFERR_NO_ERROR) {

                    // メッセージ部分に表示するテキストを設定する
                    error = _dialog->SetMessageText("in\nSFZTitleBevelFrame\n\nThis is a notification message.");
                    if (error == SFERR_NO_ERROR) {

                        // OK ボタン部分に表示するテキストを設定する
                        error = _dialog->SetButtonText("OK");

                        if (error == SFERR_NO_ERROR) {

                            // フレームのタイトルを設定する
                            error = _frame->SetText("SFZTitleBevelFrame");

                            if (error == SFERR_NO_ERROR) {

                                // 携帯画面領域を (10, 10) だけ縮小した領域をヒント領域として
                                // フレームに最適な領域を求めてヒント領域内に中央配置(CENTER-MIDDLE)し、
                                // その領域をフレームの実領域に設定する
                                // ※自動的にフレームの実領域をフレーム余白領域だけ縮小した領域がダイアログの実領域に設定される
                                _frame->SetRealBound(_frame->GetSuitableBound(GetLocalBound().Deflate(10, 10), SFYResponder::HORIZONTAL_CENTER, SFYResponder::VERTICAL_MIDDLE));

                                // ダイアログの状態を「可視+活性+操作可能+フォーカス」にまとめて設定する
                                _dialog->SetState(true, true, true, true);

                                // ダイアログを最前面に移動する
                                // ※自動的にフレームも最前面に移動する
                                _dialog->ToFront();
                            }
                        }
                    }
                }
            }
        }
    }

    return error;
}

// ダイアログ選択結果イベントを受信するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRApplication, OnResult, invoker, reason, result)
{
    // invoker にはダイアログが渡される
    // reason には結果イベントの P16 値が渡される
    // result には 0 が渡される

    switch (reason) {
        case SFP16_RESULT_OK:

            // OK ボタン押下時、または操作キー押下時

            // ...(省略)...
            break;

        case SFP16_RESULT_ESCAPE:

            // ESCAPE キー押下時、またはScheduleTimer 関数で設定した時間が経過した時

            // ...(省略)...
            break;
    }

    // ダイアログだけを閉じる
    // ※自動的にフレームはダイアログから切り離されて見えなくなる
    invoker->Terminate();

    return;
}
[Note] 注意

SFYResponder::Terminate 関数を呼び出してコンテントレスポンダを終了すると、 アタッチメントフレームはコンテントレスポンダから切り離されて見えなくなり、 他のレスポンダに装着可能な通常のフレームに戻ります。

逆に、アタッチメントフレームを終了した場合は、 アタッチメントフレームだけが見えなくなるだけです。 コンテントレスポンダはそのままです。