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

9.16. コントロール(基礎編)

コントロールは、コンテナ内に配置されるように設計されたレスポンダです。

すべてのコントロールは SFYControl クラスを継承し、最大値・最小値・現在値を保持しています。これらの値の表す意味はコントロールの種類により異なります。

具象コントロールはアプレット開発ですぐに使うことができる部品であり、抽象コントロールはカスタマイズされたユーザー定義コントロールを作成するための起点となります。

表 9.22. 具象コントロールの種類

クラス名 解説
SFZSingleTextLabelControl 単一行の編集不可能なテキストを表示するラベルコントロールです。
SFZSingleEditLabelControl 単一行の編集可能なテキストを表示するラベルコントロールです。
SFZMultipleTextLabelControl 複数行の編集不可能なテキストを表示するラベルコントロールです。
SFZMultipleEditLabelControl 複数行の編集可能なテキストを表示するラベルコントロールです。
SFZImageLabelControl イメージを表示するラベルコントロールです。
SFZSingleTextBoxControl 単一行の編集不可能なテキストを表示するボックスコントロールです。
SFZSingleEditBoxControl 単一行の編集可能なテキストを表示するボックスコントロールです。
SFZMultipleTextBoxControl 複数行の編集不可能なテキストを表示するボックスコントロールです。
SFZMultipleEditBoxControl 複数行の編集可能なテキストを表示するボックスコントロールです。
SFZImageBoxControl イメージを表示するボックスコントロールです。
SFZTextButtonControl テキストを表示するボタンコントロールです。
SFZImageButtonControl イメージを表示するボタンコントロールです。
SFZComboBoxControl コンボボックスコントロールです。
SFZListBoxControl リストボックスコントロールです。
SFZCheckboxControl チェックボックスコントロールです。
SFZRadiobuttonControl ラジオボタンコントロールです。
SFZTabControl タブコントロールです。
SFZTabPage タブコントロールのタブページです。
SFZWebBrowserControl 簡易ウェブブラウザコントロールです。
SFZScrollBarControl スクロールバーコントロールです。
SFZBandScrollBarControl 帯コントロール用のスクロールバーコントロールです。
SFZSoftKeyControl ソフトキーコントロールです。

表 9.23. 抽象コントロールの種類

クラス名 解説
SFYControl コントロールを表す抽象クラスです。
SFYLabelControl ラベルコントロールを表す抽象クラスです。
SFYBoxControl ボックスコントロールを表す抽象クラスです。
SFYButtonControl ボタンコントロールを表す抽象クラスです。
SFYCheckboxControl チェックボックスコントロールを表す抽象クラスです。
SFYRadiobuttonControl ラジオボタンコントロールを表す抽象クラスです。
SFYBandControl 帯コントロールの抽象クラスです。
SFYTabControl タブコントロールの抽象クラスです。
SFYScrollBarControl スクロールバーを表すコントロールの抽象クラスです。
[Important] 重要

すべてのコントロールにおいて、SFYResponder::SetParent 関数、SFYResponder::SetState 関数、SFYResponder::SetRealBound 関数の呼び出しは必須です。

その他の関数は必要に応じて呼び出します。省略することも可能です。

9.16.1. 単一行の編集不可能なテキストを表示するラベルコントロール [SFZSingleTextLabelControl]

図 9.42. 動作例(左:操作不可能モード、右:操作可能モード)

動作例(左:操作不可能モード、右:操作可能モード)

このコントロールには、操作可能モードと操作不可能モードの2種類の使用方法があります。

操作可能モードではコントロールをフォーカスすることができ、セレクトキー押下時にイベントを受信できます。

文字数が多くスクロールして表示する必要がある場合には、フォーカスされているときに自動的にスクロールを開始します。

操作不可能モードでは単純なラベルコントロールとして動作します。

例 9.76. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZSingleTextLabelControlSmp _label;

    ...
private:
    SFCError Make(Void);

    // 操作可能モードでセレクトキー押下時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.77. 実装

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

    if ((_label = SFZSingleTextLabelControl::NewInstance(&error)) != null) {
        error = _label->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // 操作可能モードでセレクトキー押下時の結果イベントを処理するハンドラを登録する
            // 操作不可能モードの場合、ハンドラは登録しない
            error = _label->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 表示するテキストを設定する
                // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                error = _label->SetText("hello world");
                if (error == SFERR_NO_ERROR) {
                    _label->SetRealBound(_label->GetSuitableBound().SetOrigin(10, 10));

                    // 操作可能モードの場合 : すべての状態を true に設定する
                    // 操作不可能モードの場合 : 操作可能状態を false に設定する
                    // 例:true, true, false, false
                    _label->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// 操作可能モードでセレクトキー押下時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    return;
}

9.16.2. 単一行の編集可能なテキストを表示するラベルコントロール [SFZSingleEditLabelControl]

図 9.43. 動作例(標準入力モード)

動作例(標準入力モード)

図 9.44. 動作例(パスワード入力モード)

動作例(パスワード入力モード)

このコントロールには、操作可能モードと操作不可能モードの2種類の使用方法があります。

操作可能モードではコントロールをフォーカスすることができ、セレクトキー押下時にテキスト入力画面に遷移し、入力終了時にイベントを受信できます。

文字数が多くスクロールして表示する必要がある場合には、フォーカスされているときに自動的にスクロールを開始します。

操作不可能モードでは単純なラベルコントロールとして動作します。

例 9.78. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZSingleEditLabelControlSmp _label;

    ...
private:
    SFCError Make(Void);

    // 操作可能モードで入力終了時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.79. 実装

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

    if ((_label = SFZSingleEditLabelControl::NewInstance(&error)) != null) {
        error = _label->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // 操作可能モードで入力終了時の結果イベントを処理するハンドラを登録する
            // 操作不可能モードの場合、ハンドラは登録しない
            error = _label->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 数字入力モードを ON に設定する
                _label->SetInputMode(AEE_TM_NUMBERS);

                // パスワード入力モードを ON に設定する
                error = _label->SetPasswordMode(true);
                if (error == SFERR_NO_ERROR) {

                    // 表示するテキストを設定する
                    // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                    error = _label->SetText("0123456789");
                    if (error == SFERR_NO_ERROR) {
                        _label->SetRealBound(_label->GetSuitableBound().SetOrigin(10, 10));

                        // 操作可能モードの場合 : すべての状態を true に設定する
                        // 操作不可能モードの場合 : 操作可能状態を false に設定する
                        // 例:true, true, false, false
                        _label->SetState(true, true, true, true);
                    }
                }
            }
        }
    }
    return error;
}

// 操作可能モードで入力終了時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    switch (reason) {
        case SFP16_RESULT_OK:

            // 入力が正常に終了した場合、result は GetCurrentValue 関数の戻り値となる
            // 入力されたテキストを取得する
            text = _label->GetText();

            TRACE("%S", text.GetCString());
            break;
        case SFP16_RESULT_ERROR:

            // 入力が失敗した場合、result は SFCError 型のエラー値となる
            break;
    }
    return;
}

9.16.3. 複数行の編集不可能なテキストを表示するラベルコントロール [SFZMultipleTextLabelControl]

図 9.45. 動作例(左:操作不可能モード、右:操作可能モード)

動作例(左:操作不可能モード、右:操作可能モード)

このコントロールには、操作可能モードと操作不可能モードの2種類の使用方法があります。

操作可能モードではコントロールをフォーカスすることができ、セレクトキー押下時にイベントを受信できます。

行数が多くスクロールして表示する必要がある場合には、上下キーでスクロールできます。

操作不可能モードでは単純なラベルコントロールとして動作します。

例 9.80. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZMultipleTextLabelControlSmp _label;

    ...
private:
    SFCError Make(Void);

    // 操作可能モードでセレクトキー押下時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.81. 実装

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

    if ((_label = SFZMultipleTextLabelControl::NewInstance(&error)) != null) {
        error = _label->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // 操作可能モードでセレクトキー押下時の結果イベントを処理するハンドラを登録する
            // 操作不可能モードの場合、ハンドラは登録しない
            error = _label->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 表示するテキストを設定する
                // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                error = _label->SetText("hello world\nabc\nxyz");
                if (error == SFERR_NO_ERROR) {
                    _label->SetRealBound(_label->GetSuitableBound(GetLocalBound().Deflate(10, 10)));

                    // 操作可能モードの場合 : すべての状態を true に設定する
                    // 操作不可能モードの場合 : 操作可能状態を false に設定する
                    // 例:true, true, false, false
                    _label->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// 操作可能モードでセレクトキー押下時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    return;
}

9.16.4. 複数行の編集可能なテキストを表示するラベルコントロール [SFZMultipleEditLabelControl]

図 9.46. 動作例(標準入力モード)

動作例(標準入力モード)

図 9.47. 動作例(パスワード入力モード)

動作例(パスワード入力モード)

このコントロールには、操作可能モードと操作不可能モードの2種類の使用方法があります。

操作可能モードではコントロールをフォーカスすることができ、セレクトキー押下時にテキスト入力画面に遷移し、入力終了時にイベントを受信できます。

行数が多くスクロールして表示する必要がある場合には、上下キーでスクロールできます。

操作不可能モードでは単純なラベルコントロールとして動作します。

例 9.82. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZMultipleEditLabelControlSmp _label;

    ...
private:
    SFCError Make(Void);

    // 操作可能モードで入力終了時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.83. 実装

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

    if ((_label = SFZMultipleEditLabelControl::NewInstance(&error)) != null) {
        error = _label->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // 操作可能モードで入力終了時の結果イベントを処理するハンドラを登録する
            // 操作不可能モードの場合、ハンドラは登録しない
            error = _label->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 数字入力モードを ON に設定する
                _label->SetInputMode(AEE_TM_NUMBERS);

                // パスワード入力モードを ON に設定する
                error = _label->SetPasswordMode(true);
                if (error == SFERR_NO_ERROR) {

                    // 表示するテキストを設定する
                    // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                    error = _label->SetText("0123456789\n012\n789");
                    if (error == SFERR_NO_ERROR) {
                        _label->SetRealBound(_label->GetSuitableBound(GetLocalBound().Deflate(10, 10)));

                        // 操作可能モードの場合 : すべての状態を true に設定する
                        // 操作不可能モードの場合 : 操作可能状態を false に設定する
                        // 例:true, true, false, false
                        _label->SetState(true, true, true, true);
                    }
                }
            }
        }
    }
    return error;
}

// 操作可能モードで入力終了時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    switch (reason) {
        case SFP16_RESULT_OK:

            // 入力が正常に終了した場合、result は GetCurrentValue 関数の戻り値となる
            // 入力されたテキストを取得する
            text = _label->GetText();

            TRACE("%S", text.GetCString());
            break;
        case SFP16_RESULT_ERROR:

            // 入力が失敗した場合、result は SFCError 型のエラー値となる
            break;
    }
    return;
}

9.16.5. イメージを表示するラベルコントロール [SFZImageLabelControl]

図 9.48. 動作例(左:操作不可能モード、右:操作可能モード)

動作例(左:操作不可能モード、右:操作可能モード)

このコントロールには、操作可能モードと操作不可能モードの2種類の使用方法があります。

操作可能モードではコントロールをフォーカスすることができ、セレクトキー押下時にイベントを受信できます。

操作不可能モードでは単純なラベルコントロールとして動作します。

例 9.84. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZImageLabelControlSmp _label;

    ...
private:
    SFCError Make(Void);

    // 操作可能モードでセレクトキー押下時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.85. 実装

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

    if ((_label = SFZImageLabelControl::NewInstance(&error)) != null) {
        error = _label->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // 操作可能モードでセレクトキー押下時の結果イベントを処理するハンドラを登録する
            // 操作不可能モードの場合、ハンドラは登録しない
            error = _label->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 表示するイメージを設定する
                // SFBImage オブジェクトの設定 ( リソースファイルやファイルから設定可能 )
                error = _label->SetImage(SFXPath("resource.bar"), IMAGE_ID);
                if (error == SFERR_NO_ERROR) {
                    _label->SetRealBound(_label->GetSuitableBound().SetOrigin(10, 10));

                    // 操作可能モードの場合 : すべての状態を true に設定する
                    // 操作不可能モードの場合 : 操作可能状態を false に設定する
                    // 例:true, true, false, false
                    _label->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// 操作可能モードでセレクトキー押下時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    return;
}

9.16.6. 単一行の編集不可能なテキストを表示するボックスコントロール[SFZSingleTextBoxControl]

図 9.49. 動作例

動作例

このコントロールでは、セレクトキー押下時にイベントを受信できます。

文字数が多くスクロールして表示する必要がある場合には、フォーカスされているときに自動的にスクロールを開始します。

例 9.86. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZSingleTextBoxControlSmp _box;

    ...
private:
    SFCError Make(Void);

    // セレクトキー押下時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.87. 実装

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

    if ((_box = SFZSingleTextBoxControl::NewInstance(&error)) != null) {
        error = _box->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // セレクトキー押下時の結果イベントを処理するハンドラを登録する
            error = _box->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 表示するテキストを設定する
                // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                error = _box->SetText("hello world");
                if (error == SFERR_NO_ERROR) {
                    _box->SetRealBound(_box->GetSuitableBound().SetOrigin(10, 10));
                    _box->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// セレクトキー押下時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    return;
}

9.16.7. 単一行の編集可能なテキストを表示するボックスコントロール[SFZSingleEditBoxControl]

図 9.50. 動作例(標準入力モード)

動作例(標準入力モード)

図 9.51. 動作例(パスワード入力モード)

動作例(パスワード入力モード)

このコントロールでは、セレクトキー押下時にテキスト入力画面に遷移し、入力終了時にイベントを受信できます。

文字数が多くスクロールして表示する必要がある場合には、フォーカスされているときに自動的にスクロールを開始します。

例 9.88. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZSingleEditBoxControlSmp _box;

    ...
private:
    SFCError Make(Void);

    // 入力終了時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.89. 実装

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

    if ((_box = SFZSingleEditBoxControl::NewInstance(&error)) != null) {
        error = _box->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // 入力終了時のイベントを処理するハンドラを登録する
            error = _box->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 数字入力モードを ON に設定する
                _box->SetInputMode(AEE_TM_NUMBERS);

                // パスワード入力モードを ON に設定する
                error = _box->SetPasswordMode(true);
                if (error == SFERR_NO_ERROR) {

                    // 表示するテキストを設定する
                    // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                    error = _box->SetText("0123456789");
                    if (error == SFERR_NO_ERROR) {
                        _box->SetRealBound(_box->GetSuitableBound().SetOrigin(10, 10));
                        _box->SetState(true, true, true, true);
                    }
                }
            }
        }
    }
    return error;
}

// 入力終了時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    switch (reason) {
        case SFP16_RESULT_OK:

            // 入力が正常に終了した場合、result は GetCurrentValue 関数の戻り値となる
            // 入力されたテキストを取得する
            text = _box->GetText();

            TRACE("%S", text.GetCString());
            break;
        case SFP16_RESULT_ERROR:

            // 入力が失敗した場合、result は SFCError 型のエラー値となる
            break;
    }
    return;
}

9.16.8. 複数行の編集不可能なテキストを表示するボックスコントロール[SFZMultipleTextBoxControl]

図 9.52. 動作例

動作例

このコントロールでは、セレクトキー押下時にイベントを受信できます。

行数が多くスクロールして表示する必要がある場合には、上下キーでスクロールできます。

例 9.90. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZMultipleTextBoxControlSmp _box;

    ...
private:
    SFCError Make(Void);

    // セレクトキー押下時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.91. 実装

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

    if ((_box = SFZMultipleTextBoxControl::NewInstance(&error)) != null) {
        error = _box->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // セレクトキー押下時の結果イベントを処理するハンドラを登録する
            error = _box->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 表示するテキストを設定する
                // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                error = _box->SetText("hello world\nabc\nxyz");
                if (error == SFERR_NO_ERROR) {
                    _box->SetRealBound(_box->GetSuitableBound(GetLocalBound().Deflate(10, 10)));
                    _box->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// セレクトキー押下時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    return;
}

9.16.9. 複数行の編集可能なテキストを表示するボックスコントロール[SFZMultipleEditBoxControl]

図 9.53. 動作例(標準入力モード)

動作例(標準入力モード)

図 9.54. 動作例(パスワード入力モード)

動作例(パスワード入力モード)

このコントロールでは、セレクトキー押下時にテキスト入力画面に遷移し、入力終了時にイベントを受信できます。

行数が多くスクロールして表示する必要がある場合には、上下キーでスクロールできます。

例 9.92. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZMultipleEditBoxControlSmp _box;

    ...
private:
    SFCError Make(Void);

    // 入力終了時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.93. 実装

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

    if ((_box = SFZMultipleEditBoxControl::NewInstance(&error)) != null) {
        error = _box->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // 入力終了時のイベントを処理するハンドラを登録する
            error = _box->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 数字入力モードを ON に設定する
                _box->SetInputMode(AEE_TM_NUMBERS);

                // パスワード入力モードを ON に設定する
                error = _box->SetPasswordMode(true);
                if (error == SFERR_NO_ERROR) {

                    // 表示するテキストを設定する
                    // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                    error = _box->SetText("0123456789\n012\n789");
                    if (error == SFERR_NO_ERROR) {
                        _box->SetRealBound(_box->GetSuitableBound(GetLocalBound().Deflate(10, 10)));
                        _box->SetState(true, true, true, true);
                    }
                }
            }
        }
    }
    return error;
}

// 入力終了時のイベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    switch (reason) {
        case SFP16_RESULT_OK:

            // 入力が正常に終了した場合、result は GetCurrentValue 関数の戻り値となる
            // 入力されたテキストを取得する
            text = _box->GetText();

            TRACE("%S", text.GetCString());
            break;
        case SFP16_RESULT_ERROR:

            // 入力が失敗した場合、result は SFCError 型のエラー値となる
            break;
    }
    return;
}

9.16.10. イメージを表示するボックスコントロール[SFZImageBoxControl]

図 9.55. 動作例

動作例

このコントロールでは、セレクトキー押下時にイベントを受信できます。

例 9.94. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZImageBoxControlSmp _box;

    ...
private:
    SFCError Make(Void);

    // セレクトキー押下時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.95. 実装

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

    if ((_box = SFZImageBoxControl::NewInstance(&error)) != null) {
        error = _box->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // セレクトキー押下時の結果イベントを処理するハンドラを登録する
            error = _box->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 表示するイメージを設定する
                // SFBImage オブジェクトの設定 ( リソースファイルやファイルから設定可能 )
                error = _box->SetImage(SFXPath("resource.bar"), IMAGE_ID);
                if (error == SFERR_NO_ERROR) {
                    _box->SetRealBound(_box->GetSuitableBound().SetOrigin(10, 10));
                    _box->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// セレクトキー押下時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    return;
}

9.16.11. テキストを表示するボタンコントロール [SFZTextButtonControl]

図 9.56. 動作例

動作例

このコントロールでは、ボタン操作時にイベントを受信できます。

文字数が多くスクロールして表示する必要がある場合には、フォーカスされているときに自動的にスクロールを開始します。

例 9.96. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZTextButtonControlSmp _button;

    ...
private:
    SFCError Make(Void);

    // ボタン操作時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.97. 実装

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

    if ((_button = SFZTextButtonControl::NewInstance(&error)) != null) {
        error = _button->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // ボタン操作時の結果イベントを処理するハンドラを登録する
            error = _button->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 表示するテキストを設定する
                // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                error = _button->SetText("hello world");
                if (error == SFERR_NO_ERROR) {
                    _button->SetRealBound(_button->GetSuitableBound().SetOrigin(10, 10));
                    _button->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// ボタン操作時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    return;
}

9.16.12. イメージを表示するボタンコントロール [SFZImageButtonControl]

図 9.57. 動作例

動作例

このコントロールでは、ボタン操作時にイベントを受信できます。

例 9.98. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZImageButtonControlSmp _button;

    ...
private:
    SFCError Make(Void);

    // ボタン操作時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.99. 実装

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

    if ((_button = SFZImageButtonControl::NewInstance(&error)) != null) {
        error = _button->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // ボタン操作時の結果イベントを処理するハンドラを登録する
            error = _button->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 表示するイメージを設定する
                // SFBImage オブジェクトの設定 ( リソースファイルやファイルから設定可能 )
                error = _button->SetImage(SFXPath("resource.bar"), IMAGE_ID);
                if (error == SFERR_NO_ERROR) {
                    _button->SetRealBound(_button->GetSuitableBound().SetOrigin(10, 10));
                    _button->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// ボタン操作時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    return;
}

9.16.13. リストボックスコントロール[SFZListBoxControl]

図 9.58. 動作例

動作例

リストボックスは、ユーザーに表示された複数の項目のリストの中から1つ選択させるためのコントロールです。

リストボックスは、SFZComboBoxControl クラスや SFZTextMenu クラスなどの実装で使用されます。

ユーザーがある項目を選択すると、その項目はハイライト表示されて、そのイベントが親レスポンダに送信されます。

例 9.100. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZListBoxControlSmp _listbox;

    ...
private:
    SFCError Make(Void);

    // リストボックス操作時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.101. 実装

SFCError USRWindow::Make(Void)
{
    SInt16 i;
    SFXRectangle rectangle;
    SFCError error(SFERR_NO_ERROR);

    if ((_listbox = SFZListBoxControl::NewInstance(&error)) != null) {
        error = _listbox->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // リストボックス操作時の結果イベントを処理するハンドラを登録する
            error = _listbox->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {
                for (i = 0; i < 10; ++i) {

                    // リスト項目を追加する
                    // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                    error = _listbox->Append(SFXWideString::Format("List item %d", i));

                    if (error != SFERR_NO_ERROR) break;
                }
                if (error == SFERR_NO_ERROR) {

                    // リストボックスの高さを 5 項目分にする
                    rectangle = GetLocalBound().Deflate(10, 10);
                    rectangle.SetHeight(_listbox->GetItemHeight() * 5);
                    _listbox->SetRealBound(rectangle);

                    _listbox->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// リストボックス操作時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    switch (reason) {
        case SFP16_RESULT_OK:

            // 選択された項目のテキストを取得する
            text = _listbox->GetItemText(result);
            TRACE("%S", text.GetCString());

            break;
        case SFP16_RESULT_ESCAPE:

            // クリアキー押下時、result は常に 0 となる
            break;
    }
    return;
}

9.16.14. コンボボックスコントロール[SFZComboBoxControl]

図 9.59. 動作例

動作例

コンボボックスは、ボタンコントロールを持つリストボックスとして構成されます。

コンボボックスのリストボックス部分は常に表示する方式と、ドロップ ダウン矢印のボタンが押されたときだけ表示する方式が可能です。

現在選択されている項目があれば、その項目はボタンコントロールの中に表示されます。

例 9.102. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZComboBoxControlSmp _combobox;

    ...
private:
    SFCError Make(Void);

    // コンボボックス操作時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.103. 実装

SFCError USRWindow::Make(Void)
{
    SFXRectangle rectangle;
    SInt16 i;
    SFCError error(SFERR_NO_ERROR);

    if ((_combobox = SFZComboBoxControl::NewInstance(&error)) != null) {
        error = _combobox->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // コンボボックス操作時の結果イベントを処理するハンドラを登録する
            error = _combobox->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {
                for (i = 0; i < 12; ++i) {

                    // リスト項目を追加する
                    // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                    error = _combobox->Append(SFXWideString::Format("List item %d", i));

                    if (error != SFERR_NO_ERROR) break;
                }
                if (error == SFERR_NO_ERROR) {
                    rectangle = GetLocalBound();
                    rectangle.SetHeight(SFXGraphics::GetInstance()->GetFontHeight() + 4);
                    rectangle.Deflate(10, 0);
                    rectangle.SnapTop(10);
                    _combobox->SetRealBound(_combobox->GetSuitableBound(rectangle));
                    _combobox->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// コンボボックス操作時の結果イベントを処理するハンドラ
// ユーザーが SetCurrentValue 関数で値を変更する場合も含む
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    // 選択された項目のテキストを取得する
    text = _combobox->GetItemText(result);
    TRACE("%S", text.GetCString());

    return;
}

9.16.15. チェックボックスコントロール[SFZCheckboxControl]

図 9.60. 動作例

動作例

このコントロールでは、チェックボックス操作時にイベントを受信できます。

文字数が多くスクロールして表示する必要がある場合には、フォーカスされているときに自動的にスクロールを開始します。

例 9.104. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZCheckboxControlSmp _checkbox;

    ...
private:
    SFCError Make(Void);

    // チェックボックス操作時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.105. 実装

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

    if ((_checkbox = SFZCheckboxControl::NewInstance(&error)) != null) {
        error = _checkbox->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // チェックボックス操作時の結果イベントを処理するハンドラを登録する
            error = _checkbox->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 表示するテキストを設定する
                // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                error = _checkbox->SetText("hello world");
                if (error == SFERR_NO_ERROR) {

                    // チェックされている状態に設定する
                    _checkbox->SetCurrentValue(true);

                    _checkbox->SetRealBound(_checkbox->GetSuitableBound().SetOrigin(10, 10));
                    _checkbox->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// チェックボックス操作時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    return;
}

9.16.16. ラジオボタンコントロール [SFZRadiobuttonControl]

図 9.61. 動作例

動作例

このコントロールでは、ラジオボタン操作時にイベントを受信できます。

文字数が多くスクロールして表示する必要がある場合には、フォーカスされているときに自動的にスクロールを開始します。

複数のラジオボタンコントロールをグループ化して、排他的な選択処理を自動的に行うことができます。

例 9.106. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZRadiobuttonControlSmp _radiobutton;

    ...
private:
    SFCError Make(Void);

    // ラジオボタン操作時の結果イベントを処理するハンドラ
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

例 9.107. 実装

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

    if ((_radiobutton = SFZRadiobuttonControl::NewInstance(&error)) != null) {
        error = _radiobutton->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // ラジオボタン操作時の結果イベントを処理するハンドラを登録する
            error = _radiobutton->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // 表示するテキストを設定する
                // SFXWideString オブジェクトの設定 (※リソースファイルから設定可能 )
                error = _radiobutton->SetText("hello world");
                if (error == SFERR_NO_ERROR) {

                    // チェックされている状態に設定する
                    _radiobutton->SetCurrentValue(true);

                    _radiobutton->SetRealBound(_radiobutton->GetSuitableBound().SetOrigin(10, 10));
                    _radiobutton->SetState(true, true, true, true);
                }
            }
        }
    }
    return error;
}

// ラジオボタン操作時の結果イベントを処理するハンドラ
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // reason は常に SFP16_RESULT_OK、result は GetCurrentValue 関数の戻り値となる
    return;
}

9.16.17. タブコントロールとタブページ [SFZTabControl]

図 9.62. 動作例

動作例

タブコントロールは、タブ形式での入出力機能を提供するコントロールです。

タブコントロール内のそれぞれのタブは、タブページによって管理されます。

タブコントロールの実領域は、SFYResponder::SetRealBound 関数を利用して設定する必要がありますが、 タブページの実領域はタブコントロールのローカル領域から自動的に設定されます。

具体的にはタブコントロールのローカル領域からヒント領域とタブ領域を引いた領域がタブページの実領域となります。

タブページの実領域は SFYResponder::SetRealBound 関数を利用して変更しても自動的に元のサイズに戻ります。

タブページの実領域はタブコントロールのローカル領域が変化したときにそれに合わせて自動的に再設定されます。

[Note] SFZTabPage クラスの状態について

SFZTabPage クラスのインスタンスが作成された直後、「可視」、「活性」、および「操作可能」の各状態は true に設定されます。

[Note] タブのデザイン

テキストや画像をタブのラベルとして表示するための関数が利用可能です。

例 9.108. 宣言

SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
    SFMSEALRESPONDER(USRWindow)
    SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
    SFZTabControlSmp _tab;

    ...
private:
    SFCError Make(Void);
};

例 9.109. 実装

SFCError USRWindow::Make(Void)
{
    SFBShellSmp shell;
    SFBImageSmp image;
    SFXWideString text;
    SFZTabPageSmp page[4];
    SFZTextButtonControlSmp button[4];
    SFXRectangle rectangle;
    SInt16 i;
    SFCError error(SFERR_NO_ERROR);

    if ((_tab = SFZTabControl::NewInstance(&error)) != null) {
        error = _tab->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {
            _tab->SetRealBound(GetLocalBound());
            _tab->SetBackgroundColor(SFXRGBColor(0xDD, 0xFF, 0xDD, 0x00));

            // 画面に 3 つのタブページが表示されるように設定する
            _tab->SetFieldValue(3);

            // タブコントロールの状態をまとめて設定する
            _tab->SetState(true, true, true, true);

            shell = SFBShell::GetInstance();
            if (shell != null) {

                // 4 ページ分のタブページを作成した後、追加する
                for (i = 0; i < 4; ++ i) {

                    // タブページを作成する
                    page[i] = SFZTabPage::NewInstance(&error);
                    if (page[i] != null) {

                        // タブコントロールをタブページの親レスポンダにする
                        // タブページの実領域が自動的に設定される
                        error = page[i]->SetParent(_tab);

                        if (error == SFERR_NO_ERROR) {
                            // タブページのタイトルを設定する
                            text = SFXWideString::Format("%c", 'A' + i);
                            page[i]->SetTitle(text);

                            // タブページのヒントテキストを設定する
                            text = SFXWideString::Format("Page %d", i);
                            error = page[i]->SetHint(text);
                            if (error == SFERR_NO_ERROR) {

                                // 表示するイメージをリソースファイルから読み込む
                                image = shell->LoadResImage(TAB_RES_FILE, IDI_OBJECT_5001 + i);
                                if (image != null) {

                                    // SFBImage オブジェクトの設定 ( リソースファイルやファイルから設定可能 )
                                    page[i]->SetImage(image);

                                    // タブページの状態をまとめて設定する
                                    // デフォルトの状態なのでこの行はなくても構わない
                                    page[i]->SetState(true, true, true, false);

                                    // タブページの中央にボタンを追加する
                                    if ((button[i] = SFZTextButtonControl::NewInstance(&error)) != null) {
                                        error = button[i]->SetParent(page[i]);
                                        if (error == SFERR_NO_ERROR) {
                                            error = button[i]->SetText(SFXWideString::Format("Button %c", 'A' + i));
                                            if (error == SFERR_NO_ERROR) {
                                                rectangle = button[i]->GetSuitableBound(page[i]->GetLocalBound());
                                                rectangle.SnapCenterMiddle(page[i]->GetLocalBound().GetCenterMiddle());
                                                button[i]->SetRealBound(rectangle);
                                                button[i]->SetState(true, true, true, true);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (error != SFERR_NO_ERROR) break;
                }
                if (error == SFERR_NO_ERROR) {
                    // すべてのタブページにおいて仮想領域を調整する
                    _tab->AdjustPages();

                    // 1ページ目のタブページにフォーカスを当てる
                    page[0]->SetStateFocus(true);

                    // 1ページ目のタブページを表に出す
                    // タブページは操作可能状態のとき ToFront することで自動的にフォーカスが当たるので、上の 1 行はなくても構わない
                    page[0]->ToFront();

                    // 表に出したいタブページのインデックスを指定することで、上の 2 行と同等の動作を行うことができる
                    _tab->FocusPage(0);
                }
            }
        }
    }
    return error;
}

9.16.18. コントロールを表す抽象クラス[SFYControl]

各種コントロールを実装するための起点となります。

このクラスは、最大値・最小値・現在値を実装し、いくつかの仮想関数のデフォルトの動作も実装します。

表 9.24. 仮想関数名とデフォルトの動作

仮想関数名 デフォルトの動作 オーバーライド
SFYWidget::HandleBoundRequest 推奨
SFYWidget::HandleBoundOptimize 推奨
SFYControl::HandleBoundReal 仮想領域を実領域に一致させる※1 任意
SFYWidget::HandleBoundVirtual 任意
SFYWidget::HandleBoundGlobal 任意
SFYWidget::HandleRenderRequest 必須
[Note] 注釈

※1.SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())) を実行します。つまり、仮想領域を実領域に一致させます。

以下にユーザー定義コントロールを作成するときに最低限必要なコードを示します。

例 9.110. 宣言

SFMTYPEDEFRESPONDER(USRControl)
class USRControl : public SFYControl {
    SFMSEALRESPONDER(USRControl)
    SFMRESPONDERINSTANTIATETHREE(USRControl, SFYControl, SFYWidget, SFYResponder)
public:

    // レスポンダのタイプを定義する
    // 小文字と記号のみからなるタイプは予約されているので使えない
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'C', 'N', 'T')
    };
    SFMTYPEDEFTYPE(CodeEnum)

public:
    static USRControlSmp NewInstance(SFCErrorPtr exception = null);
protected:
    explicit USRControl(Void) static_throws;
    virtual ~USRControl(Void);

    // 親クラスで定義されている仮想関数のうち、実装が推奨される仮想関数
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

例 9.111. 実装

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

        // レスポンダのタイプを設定する
        SetType(CODE_TYPE);

        // 初期化処理を記述する
    }
}

USRControl::~USRControl(Void)
{
    // 終了処理を記述する
}

USRControlSmp USRControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRControl>(Factory(::new USRControl, exception));
}

Void USRControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // コントロールに最適な大きさを計算して rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨

    return;
}

Void USRControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // コントロールに最適な大きさを rectangle パラメータ内の大きさに
    // 収まるように計算し、rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨

    return;
}

Void USRControl::HandleBoundVirtual(Void)
{
    // 仮想領域が変更された場合に再計算が必要なものがあれば、ここに記述する
    return;
}

Void USRControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // コントロールを描画する
    return;
}

9.16.19. ラベルコントロールを表す抽象クラス[SFYLabelControl]

各種ラベルコントロールを実装するための起点となります。

このクラスは、フォーカス枠の描画機能と操作キーの管理を実装し、いくつかの仮想関数のデフォルトの動作も実装します。

表 9.25. 仮想関数名とデフォルトの動作

仮想関数名 デフォルトの動作 オーバーライド
SFYLabelControl::HandleOperateKey 結果イベントを送信※1 任意
SFYWidget::HandleBoundRequest 推奨
SFYWidget::HandleBoundOptimize 推奨
SFYWidget::HandleBoundReal 仮想領域を実領域に一致させる※2 任意
SFYWidget::HandleBoundVirtual 任意
SFYWidget::HandleBoundGlobal 任意
SFYWidget::HandleRenderRequest 必須
[Note] 注釈

※1.InvokeForward(SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, GetCurrentValue()), false) を実行します。

※2.SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())) を実行します。つまり、仮想領域を実領域に一致させます。

以下にユーザー定義ラベルコントロールを作成するときに最低限必要なコードを示します。

例 9.112. 宣言

SFMTYPEDEFRESPONDER(USRLabelControl)
class USRLabelControl : public SFYLabelControl {
    SFMSEALRESPONDER(USRLabelControl)
    SFMRESPONDERINSTANTIATEFOUR(USRLabelControl, SFYLabelControl, SFYControl, SFYWidget, SFYResponder)
public:

    // レスポンダのタイプを定義する
    // 小文字と記号のみからなるタイプは予約されているので使えない
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'L', 'B', 'L')
    };
    SFMTYPEDEFTYPE(CodeEnum)

public:
    static USRLabelControlSmp NewInstance(SFCErrorPtr exception = null);
protected:
    explicit USRLabelControl(Void) static_throws;
    virtual ~USRLabelControl(Void);

    // 親クラスで定義されている仮想関数のうち、実装が推奨される仮想関数
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

例 9.113. 実装

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

        // レスポンダのタイプを設定する
        SetType(CODE_TYPE);

        // 一般的にラベルコントロールは背景を持たないので透過モードに設定する
        SetPropertyTransparent(true);

        // 初期化処理を記述する
    }
}

USRLabelControl::~USRLabelControl(Void)
{
    // 終了処理を記述する
}

USRLabelControlSmp USRLabelControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRLabelControl>(Factory(::new USRLabelControl, exception));
}

Void USRLabelControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // 親クラスが提供するフォーカス枠の描画機能を利用する場合は、
    // フォーカス枠の大きさ分だけ縮小しておく
    rectangle->Deflate(GetFocusMargin());

    // フォーカス枠内部に最適な大きさを計算して rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨


    // 親クラスが提供するフォーカス枠の描画機能を利用する場合は、
    // フォーカス枠の大きさ分だけ拡大する
    rectangle->Inflate(GetFocusMargin());
    return;
}

Void USRLabelControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // 親クラスが提供するフォーカス枠の描画機能を利用する場合は、
    // フォーカス枠の大きさ分だけ縮小しておく
    rectangle->Deflate(GetFocusMargin());

    // フォーカス枠内部に最適な大きさを rectangle パラメータ内の大きさに
    // 収まるように計算し、rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨


    // 親クラスが提供するフォーカス枠の描画機能を利用する場合は、
    // フォーカス枠の大きさ分だけ拡大する
    rectangle->Inflate(GetFocusMargin());
    return;
}

Void USRLabelControl::HandleBoundVirtual(Void)
{
    // 仮想領域が変更された場合に再計算が必要なものがあれば、ここに記述する
    return;
}

Void USRLabelControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // 親クラスが提供するフォーカス枠の描画機能を利用する場合は、
    // 以下のようにフォーカス枠を描画する
    DrawFocus(graphics, GetLocalBound());

    // フォーカス枠内部を描画する
    return;
}

9.16.20. ボックスコントロールを表す抽象クラス[SFYBoxControl]

各種ボックスコントロールを実装するための起点となります。

このクラスは、ボックスの描画機能と操作キーの管理を実装し、いくつかの仮想関数のデフォルトの動作も実装します。

表 9.26. 仮想関数名とデフォルトの動作

仮想関数名 デフォルトの動作 オーバーライド
SFYBoxControl::HandleOperateKey 結果イベントを送信※1 任意
SFYWidget::HandleBoundRequest 推奨
SFYWidget::HandleBoundOptimize 推奨
SFYControl::HandleBoundReal 仮想領域を実領域に一致させる※2 任意
SFYWidget::HandleBoundVirtual 任意
SFYWidget::HandleBoundGlobal 任意
SFYWidget::HandleRenderRequest 必須
[Note] 注釈

※1.InvokeForward(SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, GetCurrentValue()), false) を実行します。

※2.SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())) を実行します。つまり、仮想領域を実領域に一致させます。

以下にユーザー定義ボックスコントロールを作成するときに最低限必要なコードを示します。

例 9.114. 宣言

SFMTYPEDEFRESPONDER(USRBoxControl)
class USRBoxControl : public SFYBoxControl {
    SFMSEALRESPONDER(USRBoxControl)
    SFMRESPONDERINSTANTIATEFOUR(USRBoxControl, SFYBoxControl, SFYControl, SFYWidget, SFYResponder)
public:

    // レスポンダのタイプを定義する
    // 小文字と記号のみからなるタイプは予約されているので使えない
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'B', 'O', 'X')
    };
    SFMTYPEDEFTYPE(CodeEnum)

public:
    static USRBoxControlSmp NewInstance(SFCErrorPtr exception = null);
protected:
    explicit USRBoxControl(Void) static_throws;
    virtual ~USRBoxControl(Void);

    // 親クラスで定義されている仮想関数のうち、実装が推奨される仮想関数
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

例 9.115. 実装

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

        // レスポンダのタイプを設定する
        SetType(CODE_TYPE);

        // 初期化処理を記述する
    }
}

USRBoxControl::~USRBoxControl(Void)
{
    // 終了処理を記述する
}

USRBoxControlSmp USRBoxControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRBoxControl>(Factory(::new USRBoxControl, exception));
}

Void USRBoxControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // 親クラスが提供するボックスの描画機能を利用する場合は、
    // ボックスの大きさ分だけ縮小しておく
    rectangle->Deflate(GetBoxMargin());

    // ボックス内部に最適な大きさを計算して rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨


    // 親クラスが提供するボックスの描画機能を利用する場合は、
    // ボックスの大きさ分だけ拡大する
    rectangle->Inflate(GetBoxMargin());
    return;
}

Void USRBoxControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // 親クラスが提供するボックスの描画機能を利用する場合は、
    // ボックスの大きさ分だけ縮小しておく
    rectangle->Deflate(GetBoxMargin());

    // ボックス内部に最適な大きさを rectangle パラメータ内の大きさに
    // 収まるように計算し、rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨


    // 親クラスが提供するボックスの描画機能を利用する場合は、
    // ボックスの大きさ分だけ拡大する
    rectangle->Inflate(GetBoxMargin());
    return;
}

Void USRBoxControl::HandleBoundVirtual(Void)
{
    // 仮想領域が変更された場合に再計算が必要なものがあれば、ここに記述する
    return;
}

Void USRBoxControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // 親クラスが提供するボックスの描画機能を利用する場合は、
    // 以下のようにボックスを描画する
    DrawBox(graphics, GetLocalBound());

    // ボックス内部を描画する
    return;
}

9.16.21. ボタンコントロールを表す抽象クラス[SFYButtonControl]

各種ボタンコントロールを実装するための起点となります。

このクラスは、ボタンと影の描画機能と操作キーの管理を実装し、いくつかの仮想関数のデフォルトの動作も実装します。

表 9.27. 仮想関数名とデフォルトの動作

仮想関数名 デフォルトの動作 オーバーライド
SFYButtonControl::HandleOperateKey 任意
SFYButtonControl::HandleOperateKeyPress 任意
SFYButtonControl::HandleOperateKeyRelease 結果イベントを送信※1 任意
SFYWidget::HandleBoundRequest 推奨
SFYWidget::HandleBoundOptimize 推奨
SFYControl::HandleBoundReal 仮想領域を実領域に一致させる※2 任意
SFYWidget::HandleBoundVirtual 任意
SFYWidget::HandleBoundGlobal 任意
SFYWidget::HandleRenderRequest 必須
[Note] 注釈

※1.InvokeForward(SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, GetCurrentValue()), false) を実行します。

※2.SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())) を実行します。つまり、仮想領域を実領域に一致させます。

以下にユーザー定義ボタンコントロールを作成するときに最低限必要なコードを示します。

例 9.116. 宣言

SFMTYPEDEFRESPONDER(USRButtonControl)
class USRButtonControl : public SFYButtonControl {
    SFMSEALRESPONDER(USRButtonControl)
    SFMRESPONDERINSTANTIATEFOUR(USRButtonControl, SFYButtonControl, SFYControl, SFYWidget, SFYResponder)
public:

    // レスポンダのタイプを定義する
    // 小文字と記号のみからなるタイプは予約されているので使えない
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'B', 'T', 'N')
    };
    SFMTYPEDEFTYPE(CodeEnum)

public:
    static USRButtonControlSmp NewInstance(SFCErrorPtr exception = null);
protected:
    explicit USRButtonControl(Void) static_throws;
    virtual ~USRButtonControl(Void);

    // 親クラスで定義されている仮想関数のうち、実装が推奨される仮想関数
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

例 9.117. 実装

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

        // レスポンダのタイプを設定する
        SetType(CODE_TYPE);

        // 初期化処理を記述する
    }
}

USRButtonControl::~USRButtonControl(Void)
{
    // 終了処理を記述する
}

USRButtonControlSmp USRButtonControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRButtonControl>(Factory(::new USRButtonControl, exception));
}

Void USRButtonControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // 親クラスが提供するボタンと影の描画機能を利用する場合は、
    // ボタンと影の大きさ分だけ縮小しておく
    rectangle->Deflate(GetShadowMargin());
    rectangle->Deflate(GetButtonMargin());

    // ボタン内部に最適な大きさを計算して rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨


    // 親クラスが提供するボタンと影の描画機能を利用する場合は、
    // ボタンと影の大きさ分だけ拡大する
    rectangle->Inflate(GetButtonMargin());
    rectangle->Inflate(GetShadowMargin());
    return;
}

Void USRButtonControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // 親クラスが提供するボタンと影の描画機能を利用する場合は、
    // ボタンと影の大きさ分だけ縮小しておく
    rectangle->Deflate(GetShadowMargin());
    rectangle->Deflate(GetButtonMargin());

    // ボタン内部に最適な大きさを rectangle パラメータ内の大きさに
    // 収まるように計算し、rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨


    // 親クラスが提供するボタンと影の描画機能を利用する場合は、
    // ボタンと影の大きさ分だけ拡大する
    rectangle->Inflate(GetButtonMargin());
    rectangle->Inflate(GetShadowMargin());
    return;
}

Void USRButtonControl::HandleBoundVirtual(Void)
{
    // 仮想領域が変更された場合に再計算が必要なものがあれば、ここに記述する
    return;
}

Void USRButtonControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // 親クラスが提供するボタンと影の描画機能を利用する場合は、
    // 以下のようにボタンと影を描画する
    DrawButton(graphics, DrawShadow(graphics, GetLocalBound()));

    // ボタン内部を描画する
    return;
}

9.16.22. チェックボックスコントロールを表す抽象クラス[SFYCheckboxControl]

各種チェックボックスコントロールを実装するための起点となります。

このクラスは、チェックボックスと影の描画機能とチェック状態の切り替えを実装し、いくつかの仮想関数のデフォルトの動作も実装します。

表 9.28. 仮想関数名とデフォルトの動作

仮想関数名 デフォルトの動作 オーバーライド
SFYButtonControl::HandleOperateKey 任意
SFYButtonControl::HandleOperateKeyPress 任意
SFYCheckboxControl::HandleOperateKeyRelease チェック状態切り替え結果イベントの送信※1 任意
SFYWidget::HandleBoundRequest 推奨
SFYWidget::HandleBoundOptimize 推奨
SFYControl::HandleBoundReal 仮想領域を実領域に一致させる※2 任意
SFYWidget::HandleBoundVirtual 任意
SFYWidget::HandleBoundGlobal 任意
SFYWidget::HandleRenderRequest 必須
[Note] 注釈

※1.チェック状態を切り替えた後、InvokeForward(SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, GetCurrentValue()), false) を実行します。

※2.SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())) を実行します。つまり、仮想領域を実領域に一致させます。

以下にユーザー定義チェックボックスコントロールを作成するときに最低限必要なコードを示します。

例 9.118. 宣言

SFMTYPEDEFRESPONDER(USRCheckboxControl)
class USRCheckboxControl : public SFYCheckboxControl {
    SFMSEALRESPONDER(USRCheckboxControl)
    SFMRESPONDERINSTANTIATEFIVE(USRCheckboxControl, SFYCheckboxControl, SFYButtonControl, SFYControl, SFYWidget, SFYResponder)
public:

    // レスポンダのタイプを定義する
    // 小文字と記号のみからなるタイプは予約されているので使えない
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'C', 'H', 'K')
    };
    SFMTYPEDEFTYPE(CodeEnum)

public:
    static USRCheckboxControlSmp NewInstance(SFCErrorPtr exception = null);
protected:
    explicit USRCheckboxControl(Void) static_throws;
    virtual ~USRCheckboxControl(Void);

    // 親クラスで定義されている仮想関数のうち、実装が推奨される仮想関数
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

例 9.119. 実装

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

        // レスポンダのタイプを設定する
        SetType(CODE_TYPE);

        // 一般的にチェックボックスコントロールのラベル部分は背景を持たないので透過モードに設定する
        SetPropertyTransparent(true);

        // 初期化処理を記述する
    }
}

USRCheckboxControl::~USRCheckboxControl(Void)
{
    // 終了処理を記述する
}

USRCheckboxControlSmp USRCheckboxControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRCheckboxControl>(Factory(::new USRCheckboxControl, exception));
}

Void USRCheckboxControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // チェックボックスコントロールに最適な大きさを計算して rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨

    return;
}

Void USRCheckboxControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // チェックボックスコントロールに最適な大きさを rectangle パラメータ内の大きさに
    // 収まるように計算し、rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨

    return;
}

Void USRCheckboxControl::HandleBoundVirtual(Void)
{
    // 仮想領域が変更された場合に再計算が必要なものがあれば、ここに記述する
    return;
}

Void USRCheckboxControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    SFXGrid grid;

    // 親クラスが提供するチェックボックスと影の描画機能を利用する場合は、
    // 以下のようにチェックボックスと影を描画する
    // _height 変数はチェックボックス部分の高さを表し、
    // _origin 変数はチェックボックス部分の原点を表すものとする
    // 一般的にこれらの変数は、ラベル部分に使用するフォントの高さより計算する
    if (_height >= 28) {
        grid.Set(DrawShadow28(graphics, _origin));
        DrawButton27(graphics, grid);
        grid.Add(3, 3);
        DrawCheckmark21(graphics, grid);
    }
    else if (_height >= 14) {
        grid.Set(DrawShadow14(graphics, _origin));
        DrawButton13(graphics, grid);
        grid.Add(2, 2);
        DrawCheckmark09(graphics, grid);
    }

    // チェックボックスコントロールのラベル部分を描画する
    return;
}

9.16.23. ラジオボタンコントロールを表す抽象クラス[SFYRadiobuttonControl]

各種ラジオボタンコントロールを実装するための起点となります。

このクラスは、ラジオボタンと影の描画機能と排他的なチェック状態の切り替えを実装し、いくつかの仮想関数のデフォルトの動作も実装します。

表 9.29. 仮想関数名とデフォルトの動作

仮想関数名 デフォルトの動作 オーバーライド
SFYButtonControl::HandleOperateKey 任意
SFYButtonControl::HandleOperateKeyPress 任意
SFYRadiobuttonControl::HandleOperateKeyRelease 排他的なチェック状態切り替え結果イベントの送信※1 任意
SFYWidget::HandleBoundRequest 推奨
SFYWidget::HandleBoundOptimize 推奨
SFYControl::HandleBoundReal 仮想領域を実領域に一致させる※2 任意
SFYWidget::HandleBoundVirtual 任意
SFYWidget::HandleBoundGlobal 任意
SFYWidget::HandleRenderRequest 必須
[Note] 注釈

※1.排他的にチェック状態を切り替えた後、InvokeForward(SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, GetCurrentValue()), false) を実行します。

※2.SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())) を実行します。つまり、仮想領域を実領域に一致させます。

以下にユーザー定義ラジオボタンコントロールを作成するときに最低限必要なコードを示します。

例 9.120. 宣言

SFMTYPEDEFRESPONDER(USRRadiobuttonControl)
class USRRadiobuttonControl : public SFYRadiobuttonControl {
    SFMSEALRESPONDER(USRRadiobuttonControl)
    SFMRESPONDERINSTANTIATESIX(USRRadiobuttonControl, SFYRadiobuttonControl, SFYCheckboxControl, SFYButtonControl, SFYControl, SFYWidget, SFYResponder)
public:

    // レスポンダのタイプを定義する
    // 小文字と記号のみからなるタイプは予約されているので使えない
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'R', 'D', 'O')
    };
    SFMTYPEDEFTYPE(CodeEnum)

public:
    static USRRadiobuttonControlSmp NewInstance(SFCErrorPtr exception = null);
protected:
    explicit USRRadiobuttonControl(Void) static_throws;
    virtual ~USRRadiobuttonControl(Void);

    // 親クラスで定義されている仮想関数のうち、実装が推奨される仮想関数
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

例 9.121. 実装

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

        // レスポンダのタイプを設定する
        SetType(CODE_TYPE);

        // 一般的にラジオボタンコントロールのラベル部分は背景を持たないので透過モードに設定する
        SetPropertyTransparent(true);

        // 初期化処理を記述する
    }
}

USRRadiobuttonControl::~USRRadiobuttonControl(Void)
{
    // 終了処理を記述する
}

USRRadiobuttonControlSmp USRRadiobuttonControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRRadiobuttonControl>(Factory(::new USRRadiobuttonControl, exception));
}

Void USRRadiobuttonControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // ラジオボタンコントロールに最適な大きさを計算して rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨

    return;
}

Void USRRadiobuttonControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // ラジオボタンコントロールに最適な大きさを rectangle パラメータ内の大きさに
    // 収まるように計算し、rectangle パラメータに設定する
    // 原点は変更せず、サイズだけを設定することを推奨

    return;
}

Void USRRadiobuttonControl::HandleBoundVirtual(Void)
{
    // 仮想領域が変更された場合に再計算が必要なものがあれば、ここに記述する
    return;
}

Void USRRadiobuttonControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    SFXGrid grid;

    // 親クラスが提供するラジオボタンと影の描画機能を利用する場合は、
    // 以下のようにラジオボタンと影を描画する
    // _height 変数はラジオボタン部分の高さを表し、
    // _origin 変数はラジオボタン部分の原点を表すものとする
    // 一般的にこれらの変数は、ラベル部分に使用するフォントの高さより計算する
    if (_height >= 28) {
        grid.Set(DrawShadow28(graphics, _origin));
        DrawButton27(graphics, grid);
        grid.Add(8, 8);
        DrawCheckmark11(graphics, grid);
    }
    else if (_height >= 14) {
        grid.Set(DrawShadow14(graphics, _origin));
        DrawButton13(graphics, grid);
        grid.Add(4, 4);
        DrawCheckmark05(graphics, grid);
    }

    // ラジオボタンコントロールのラベル部分を描画する
    return;
}

9.16.24. ソフトキーコントロール[SFZSoftKeyControl]

ソフトキーコントロール(SFZSoftKeyControl)は、 3つのソフトキーラベルから構成されるソフトキーメニュー(スタンダードスタイル)と、 5つのソフトキーラベルから構成されるソフトキーメニュー(エクステンションスタイル)の機能を提供するコントロールです。 デフォルトはスタンダードスタイルです。

図 9.63. 動作例1: スタンダードスタイル


動作例1: スタンダードスタイル

ソフトキーコントロール(スタンダードスタイル) : 3つのソフトキーラベルから構成されるソフトキーメニュー

図 9.64. 動作例2: エクステンションスタイル


動作例2: エクステンションスタイル

ソフトキーコントロール(エクステンションスタイル) : 5つのソフトキーラベルから構成されるソフトキーメニュー

■ソフトキーコントロールの機能

ソフトキーコントロール(SFZSoftKeyControl)が提供する機能は以下のとおりです。

  1. ソフトキーコントロールとレスポンダの関連付けとその解消
  2. ソフトキーウィンドウの描画と切り替え
  3. ソフトキー1〜4、セレクトキー、左右上下キーに関するラベルに関する各種設定と描画
  4. ソフトキー1〜4のキーイベントの処理(ソフトキーコントロールに関連付けられたレスポンダにソフトキーイベントを送信します)
  5. ソフトキーコントロールのソフトキーメニューの表示切り替えは、バインドされたレスポンダのフォーカス状態の「視覚的 ON/OFF」 のタイミングで行われます。

レスポンダのフォーカス状態の「視覚的 ON/OFF」 については、状態をご覧ください。

■SFZSoftKeyControl クラスの使い方

以下、window1 と window2 のウィンドウを持つ application アプリケーションクラスがあるとして説明します。

  1. ソフトキーコントロールのインスタンスを生成します。

    // 1アプレットにつき1つのソフトキーコントロールのインスタンスが有効
    _softkey = SFZSoftKeyControl::NewInstance(&error);
    
  2. ソフトキーコントロールの親を application アプリケーションクラス[ルート(SFZRoot クラス)]にします(ルートの子レスポンダの中で常に最前面になるように自動的に配置されます)。

    // ソフトキーコントロールの親は必ずアプリケーションクラスにする
    _softkey->SetParent(application);
    
  3. ソフトキーコントロールのスタイル(スタンダードかエクステンション)を設定します。

    // ソフトキーコントロールのスタイルをエクステンションに設定する
    _softkey->SetStyle(SFZSoftKeyControl::EXTENSION);
    
  4. ソフトキーコントロールの実領域を設定します。

    // ソフトキーコントロールの実領域を自動的に計算して設定する
    _softkey->SetRealBound(_softkey->GetSuitableBound());
    
  5. ソフトキーコントロールの状態を設定します。必ず「可視+活性+操作不可能+非フォーカス」の状態で設定します。

    // ソフトキーコントロールの状態を「可視+活性+操作不可能+非フォーカス」でまとめて設定する
    _softkey->SetState(true, true, false, false);
    
  6. ラベルに表示されるテキスト、イメージ、カラー(3色の構造体)をキーを指定して登録します。(※テキスト、イメージ、カラーは異なるラベル間で共有することができ、それぞれユニークなキーで管理されます。)

    // ソフトキーコントロールのラベルに表示されるテキスト、イメージ、カラーを登録する
    _softkey->RegisterText(KEY_TEXT, text);
    _softkey->RegisterImage(KEY_IMAGE, image);
    _softkey->RegisterColor(KEY_COLOR, color);
    
  7. メニューキーを指定してソフトキーメニューを作成します。(※メニューは異なるレスポンダ間で共有することができ、ユニークなキーで管理されます。)

    // ソフトキーコントロールのメニューを作成する
    _softkey->CreateMenu(KEY_MENU);
    
  8. ソフトキーメニューにあらかじめ登録しておいたテキスト、イメージ、カラーのキーをセットします。

    // ソフトキー1のラベルに対してテキスト、イメージ、カラーをセットする
    _softkey->SetTextKey(KEY_MENU, SFZSoftKeyControl::SOFTKEY_1, KEY_TEXT);
    _softkey->SetImageKey(KEY_MENU, SFZSoftKeyControl::SOFTKEY_1, KEY_IMAGE);
    _softkey->SetColorKey(KEY_MENU, SFZSoftKeyControl::SOFTKEY_1, KEY_COLOR);
    
  9. window1 と共にソフトキーコントロールを表示します。

    window1 のコンストラクタ内で以下の処理を行います。

    [Note] SophiaFramework 標準レスポンダの場合

    window1 が標準レスポンダ (SFZWindow や SFZTextMenu など) でコンストラクタを編集できない場合、 下記の処理は外部から行います。

    1. ソフトキーコントロールのインスタンスを取得します。

      // ソフトキーコントロールのインスタンスを取得する
      _softkey = USRApplication::GetSoftKey();
      

      ※ USRApplication クラスにソフトキーコントロールのインスタンスを取得する関数を定義しているとします。

    2. window1 と ソフトキーメニュー、ソフトキーコントロールをバインドします。

      // ソフトキーコントロールとウィンドウをバインドする
      _softkey->Bind(this, MENU_KEY);
      
    3. ソフトキーコントロールのハンドラを登録します。

      // ソフトキーイベントのハンドラを登録する
      _softkey->RegisterHandler(
                            SFXEventRange(SFEVT_RESPONDER_SOFTKEY, SFEVT_RESPONDER_SOFTKEY, AVK_SOFT1, AVK_SOFT4), 
                            XANDLER_INTERNAL(OnSoftkey)
      );
      // ※ソフトキーイベントのハンドラ OnSoftkey の宣言と実装も必要
      
    4. このソフトキーコントロールを表示する必要がなくなればアンバインドします。

      // ソフトキーコントロールとウィンドウをアンバインドする
      // バインドされたレスポンダが無効になれば自動的にアンバイドされるので省略可能
      _softkey->UnBind(this);
      
  10. window2 も window1 と同様です。
[Note] 複数のレスポンダとソフトキーコントロールの管理

ソフトキーコントロールはソフトキーメニューを設定し、複数のレスポンダとバインドして利用します。

バインドしているレスポンダのどれかのソフトキーメニューを表示すべきとき『ソフトキーコントロールはアクティブである』と呼びます。

そのとき、バインドされたレスポンダの中で最も前面にあるフォーカスを持つレスポンダのソフトキーメニューが表示されます。

アクティブなソフトキーコントロールは、そのレスポンダにソフトキー1〜4のキーイベントを転送します。

ソフトキーコントロールが非アクティブである場合、ソフトキー1〜4のキーイベントは他のレスポンダに転送されません。

[Caution] ソフトキーコントロール利用時の注意事項

ソフトキーコントロールを利用すると、ソフトキーコントロール内部で下記のようにアプリケーションクラスのトレーサに配信規則が登録されます。

// ソフトキーコントロールの親レスポンダをアプリケーションクラスに設定したとき
// トレーサには下記の配信規則が登録される
application->RegisterTracer(
                   SFXEventRange(SFEVT_KEY, SFEVT_KEY, AVK_SOFT1, AVK_SOFT4),
                   SFYTracer::ORDER_FORWARD, 
                   SFYTracer::STATE_ALL, 
                   false
);

配信規則は、

  1. ソフトキー1〜4のキーイベントを状態に関係なくすべてのレスポンダを対象として前面から背面へ配信する
  2. イベントが処理されるとそこで処理を終了する(重複処理はしない)

となっています。

ソフトキーコントロールはアプリケーションクラス[ルート(SFZRoot クラス)]の最前面の子レスポンダなので、 ソフトキー1〜4のキーイベントは必ずソフトキーコントロール内で処理されます。

ソフトキーコントロールはソフトキー1〜4のキーイベントを表示中のソフトキーメニューにバインドされたレスポンダへ転送します。

ソフトキーメニューが表示されていない場合、 ソフトキー1〜4のキーイベントはどのレスポンダにも転送されません。

関連情報 : トレーサ | ハンドラ | ルート | SFZRoot

例 9.122. ソフトキーコントロールの定義と生成

// screensaver_sfy アプリケーションクラスの定義
SFMTYPEDEFCLASS(screensaver_sfy)
class screensaver_sfy : public SFYApplication {
    SFMSEALCOPY(screensaver_sfy)
private:
    SFZSoftKeyControlSmp _softkey; // ソフトキーコントロールはアプリケーションクラスのグローバル変数として保持する
    MainWindowSmp _main;
public:
    static SFCInvokerPtr Factory(Void);
    static SFZSoftKeyControlSmp GetSoftKey(Void);
private:
    explicit screensaver_sfy(Void) static_throws;
    virtual ~screensaver_sfy(Void);
    XANDLER_DECLARE_VOIDRENDER(OnRenderRequest)
};

// screensaver_sfy アプリケーションクラスのコンストラクタ
screensaver_sfy::screensaver_sfy(Void) static_throws
{
    SFCError error;

    if (static_try()) {
        // 最初にソフトキーコントロールを作成する(ソフトキーコントロールはルートの最前面の子レスポンダ)
        if (static_try()) {
           // アプリケーションクラスは1つだけソフトキーコントロールを持てる
           // ソフトキーコントロールを使うとき、
           // ソフトキー1〜4のキーイベントはすべてソフトキーコントロール内で処理される
           _softkey = SFZSoftKeyControl::NewInstance(&error);
            if (_softkey != null) {
                // 親レスポンダはアプリケーションクラスルート)とする
                // ※ソフトキーコントロールはルートの子レスポンダでなければいけない
                error = _softkey->SetParent(GetThis());
                if (error == SFERR_NO_ERROR) {
                    // スタイルを設定する(ここではエクステンションスタイルのソフトキーコントロール)
                    _softkey->SetStyle(SFZSoftKeyControl::EXTENSION);
                    // 実領域を設定する(携帯電話の画面のサイズとスタイルから自動的に計算して設定)
                    _softkey->SetRealBound(_softkey->GetSuitableBound());
                    // 状態を「可視+活性+操作不可能+非フォーカス」にまとめて設定する
                    _softkey->SetState(true, true, false, false);
                    // 最前面に配置する(常に最前面になるように内部処理される)
                    // _softkey->ToFront(); // 内部的に自動的に実行されるので不要

                    // 適宜、ソフトキーにテキスト(、イメージ、カラー)を割り当てます。
                    // レスポンダとソフトキーメニューがバインドされ、テキスト(、イメージ、カラー)が、
                    // 実際に使用されてしまう前に割り当てる必要があります。
                    _softkey->RegisterText(KEY_TEXT_EXIT,     SFXWideString("終了"));
                    _softkey->RegisterText(KEY_TEXT_EDIT,     SFXWideString("設定"));
                    _softkey->RegisterText(KEY_TEXT_ADD,      SFXWideString("追加"));
                    _softkey->RegisterText(KEY_TEXT_CHANGE,   SFXWideString("変更"));
                    _softkey->RegisterText(KEY_TEXT_REMOVE,   SFXWideString("削除"));

                    // 適宜、ソフトキーメニューを作成しラベルのキーをセットします。
                    // レスポンダとソフトキーメニューがバインドされる前に作成する必要があります。
                    _softkey->CreateMenu(KEY_MENU_MAIN);
                    // それぞれ SELECT, SOFTKEY_1, SOFTKEY_2, SOFTKEY_3, SOFTKEY_4 のラベルに対応します。
                    UInt32 key_text[] = {KEY_TEXT_EDIT, KEY_TEXT_EXIT, KEY_TEXT_ADD, KEY_TEXT_CHANGE, KEY_TEXT_REMOVE};
                    _softkey->SetTextKey(KEY_MENU_MAIN, key_text, lengthof(key_text));
                }
            }
        }

        // 次にメイン ウィンドウを作成する
        if (error == SFERR_NO_ERROR) {
            _main = MainWindow::NewInstance(&error);

                .................

        }


        .................
    }
}

// ソフトキーコントロールのインスタンスを取得する関数の定義
SFZSoftKeyControlSmp screensaver_sfy::GetSoftKey(Void)
{
    SFZSoftKeyControlSmp softkey(static_pointer_cast<SFZSoftKeyControl>(GetRoot()->GetChildFront()));

    if (softkey == null || softkey->GetType() != SFZSoftKeyControl::CODE_TYPE) {
        softkey = SFZSoftKeyControlSmp::EmptyInstance();
    }
    return softkey;
}

例 9.123. ソフトキーコントロールの作成とソフトキーハンドラの宣言・登録

// ソフトキーコントロールの定義とハンドラの宣言
SFMTYPEDEFRESPONDER(MainWindow)
class MainWindow : public SFZWindow {
    SFMSEALRESPONDER(MainWindow)
    SFMRESPONDERINSTANTIATEFOUR(MainWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
public:

        ................

private:
    SFZSoftKeyControlSmp _softkey;// ソフトキーコントロール

        ................

private:
    XANDLER_DECLARE_VOIDEVENT(OnKey)     // キーハンドラ
    XANDLER_DECLARE_VOIDEVENT(OnSoftkey) // ソフトキーハンドラ

        ................

};

// MainWindow のコンストラクタ
// ソフトキーコントロールのバインド、各種設定、ハンドラ登録
MainWindow::MainWindow(Void) static_throws
{
    static SFXEventRange::AtomRecConst range[] = {
        {SFEVT_APP_SUSPEND, SFEVT_APP_SUSPEND, SFP16_BEGIN, SFP16_END},
        {SFEVT_APP_RESUME, SFEVT_APP_RESUME, SFP16_BEGIN, SFP16_END},
        {SFEVT_KEY, SFEVT_KEY, SFP16_BEGIN, SFP16_END},
        {SFEVT_RESPONDER_SOFTKEY, SFEVT_RESPONDER_SOFTKEY, AVK_SOFT1, AVK_SOFT4}  // ソフトキーコントロールのイベント
    };
    SFYHandler::RuleRec rule[lengthof(range)];

    if (static_try()) {
        SetType(CODE_TYPE);
        // ハンドラの登録
        rule[0].spp = XANDLER_FUNCTION(OnSuspend);
        rule[0].reference = this;
        rule[1].spp = XANDLER_FUNCTION(OnResume);
        rule[1].reference = this;
        rule[2].spp = XANDLER_FUNCTION(OnKey);
        rule[2].reference = this;
        rule[3].spp = XANDLER_FUNCTION(OnSoftkey); // ソフトキーコントロールのハンドラ
        rule[3].reference = this;
        static_throw(RegisterHandler(atomic_cast(range), rule, lengthof(range)));

        // ソフトキーコントロールの設定
        // ソフトキーコントロールのインスタンスを取得する
        if ((_softkey = screensaver_sfy::GetSoftKey()) != null) {
           // ソフトキーコントロールを MainWindow、MENU_KEY_MAIN にバインドする
           // ※ 以下の関数呼び出しでバインドするレスポンダの引数は SFYResponderPtr 型を要求しているので this を指定している
           _softkey->Bind(this, MENU_KEY_MAIN);
        }
    }
}

例 9.124. ソフトキーコントロールのハンドラの実装

// ソフトキーコントロールのハンドラの実装 : ソフトキー1〜4のキーイベントを受信したときのハンドラ
// ソフトキーコントロールにバインドされたフォーカスを持つ他のレスポンダよりも前面にあり、
// MainWindow がフォーカスを持つ場合にしか呼び出されない
XANDLER_IMPLEMENT_VOIDEVENT(MainWindow, OnSoftkey, invoker, event)
{

                .................


    switch (event.GetP16()) {
        case AVK_SOFT1:
            //  終了確認ダイアログの作成

                .................

            break;
        case AVK_SOFT2:
            // メニューの作成

                .................

}