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

9.11. コンテナ(基礎編)

コンテナは、コントロール内および他のコンテナ(コンテナ・ウィンドウ・ダイアログ)内に配置されるように設計されたレスポンダです。

すべてのコンテナは SFYContainer クラスを継承します。

SFYContainer は、 実領域よりも大きい 仮想領域を上下にスクロールしたり、 コンテナ内のレスポンダ間でフォーカスを移動させる機能を提供します。 このとき、スクロールはフォーカス移動と連動して行われます。

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

[Caution] 注意
ウィンドウやダイアログはコンテナの一種ですが、これらのレスポンダはルート内に配置される点が他のコンテナと異なります。

表 9.8. 具象コンテナの種類

クラス名 解説
SFZContainer コントロールやコンテナなどを配置する汎用コンテナです。
SFZWindow コントロールやコンテナなどを配置する汎用ウィンドウです。
SFZDialog コントロールやコンテナなどを配置する汎用ダイアログです。
SFZTabPage SFZTabControlに追加できる具象コンテナです。
[Important] 重要

すべての具象コンテナにおいて、 SFYResponder::SetParent 関数、 SFYResponder::SetState 関数、 SFYResponder::SetRealBound 関数の呼び出しは必須です。

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

表 9.9. 抽象コンテナの種類

クラス名 解説
SFYContainer コンテナを表す抽象クラスです。
SFZWindow ウィンドウを表す抽象クラスです。
SFZDialog ダイアログを表す抽象クラスです。

9.11.1. コントロールやコンテナなどを配置する汎用コンテナ[SFZContainer]

SFZContainer は、 各種コントロールやコンテナを配置するための汎用的なコンテナとして機能します。

コンテナ内にコントロールやコンテナが配置されている場合、 SFYContainer::SetScrollDownKey / SFYContainer::SetScrollUpKey / SFYContainer::SetPageDownKey / SFYContainer::SetPageUpKey / SFYContainer::SetSnapDownKey / SFYContainer::SetSnapUpKey 関数で設定するスクロールキーを使用してコンテナ内のレスポンダ間でフォーカスを移動できます。

仮想領域実領域よりも大きい場合は、 フォーカス移動と連動した、仮想領域の上下方向へのスクロール機能も利用できます。

[Caution] コンテナとウィンドウやダイアログの違い

コンテナは、以下の点においてウィンドウやダイアログと異なります。

  • コンテナはコンテナ内に配置できます。
  • コンテナはコントロール内に配置できます。
  • コンテナは、 ルート[SFZRoot]内に配置しません。

※ウィンドウやダイアログは、 ルート[SFZRoot](または 枠線やタイトルを付ける場合はフレーム)内に配置します。

図 9.30. 動作例

動作例

例 9.52. 宣言

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

    // ...(省略)...
private:
    SFCError Make(Void);
};

例 9.53. 実装

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

    // コンテナを生成する
    if ((_container = SFZContainer::NewInstance(&error)) != null) {

        // コンテナの親レスポンダを USRWindow に設定する
        error = _container->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // コンテナの背景色を薄赤色に設定する
            // ※コンテナの背景は SFYWidget::OnRenderRequest ハンドラによって描画される
            _container->SetBackgroundColor(SFXRGBColor(0xFF, 0xCC, 0xCC, 0x00));

            // コンテナの実領域を USRWindow の領域を (10, 10) だけ縮小した領域に設定する
            _container->SetRealBound(GetLocalBound().Deflate(10, 10));

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

    return error;
}

9.11.2. コンテナを表す抽象クラス[SFYContainer]

SFYContainer は各種コンテナを実装するための起点(基底クラス)となります。

たとえば、 SFZContainerSFZWindowSFZDialogSFYContainer クラスを継承して実装されています。

コンテナ内にコントロールやコンテナが配置されている場合、 SFYContainer::SetScrollDownKey / SFYContainer::SetScrollUpKey / SFYContainer::SetPageDownKey / SFYContainer::SetPageUpKey / SFYContainer::SetSnapDownKey / SFYContainer::SetSnapUpKey 関数で設定するスクロールキーを使用してコンテナ内のレスポンダ間でフォーカスを移動できます。

仮想領域実領域よりも大きい場合は、 フォーカス移動と連動した、仮想領域の上下方向へのスクロール機能も利用できます。

SFYContainer を継承するレスポンダでは、 SFYContainer::SFYContainer / SFYWidget::SFYWidget コンストラクタで登録されたハンドラの処理により、 下記のイベントを受信すると、対応する下記の仮想関数(ハンドラ)が最初に呼び出されます。 その後、開発者がレスポンダに登録したハンドラが呼び出されることになります。

[Note] 注意

ハンドラの詳細については、 SFYContainer::SFYContainer / SFYWidget::SFYWidget コンストラクタの解説を参照してください。

[Tip] Tip

ハンドラを登録する手間を省略できるので、 通常、これらのイベント処理は仮想関数をオーバーライドして記述します。

表 9.10. イベント、仮想関数(ハンドラ)とデフォルト動作

イベント 仮想関数(ハンドラ) デフォルトの動作 オーバーライド
SFYContainer::SetScrollUpKey で設定された ScrollUp キーの SFEVT_KEY イベント SFYContainer::HandleScrollUpKey 仮想領域を上方向にスクロールする※1 任意
SFYContainer::SetScrollDownKey で設定された ScrollDown キーの SFEVT_KEY イベント SFYContainer::HandleScrollDownKey 仮想領域を下方向にスクロールする※2 任意
SFYContainer::SetPageUpKey で設定された PageUp キーの SFEVT_KEY イベント SFYContainer::HandlePageUpKey 仮想領域を上方向に 1 ページ分スクロールする※3 任意
SFYContainer::SetPageDownKey で設定された PageDown キーの SFEVT_KEY イベント SFYContainer::HandlePageDownKey 仮想領域を下方向に 1 ページ分スクロールする※4 任意
SFYContainer::SetSnapUpKey で設定された SnapUp キーの SFEVT_KEY イベント SFYContainer::HandleSnapUpKey 仮想領域を上端までスクロールする※5 任意
SFYContainer::SetSnapDownKey で設定された SnapDown キーの SFEVT_KEY イベント SFYContainer::HandleSnapDownKey 仮想領域を下端までスクロールする※6 任意
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REQUEST) イベント SFYWidget::HandleBoundRequest 推奨
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_OPTIMIZE) イベント SFYWidget::HandleBoundOptimize 推奨
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REAL) イベント SFYWidget::HandleBoundReal 任意
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_VIRTUAL) イベント SFYWidget::HandleBoundVirtual 任意
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_GLOBAL) イベント SFYWidget::HandleBoundGlobal 非推奨[廃止予定]
(SFEVT_RESPONDER_RENDER, SFP16_RENDER_REQUEST) イベント SFYWidget::HandleRenderRequest 任意

※デフォルトの動作にある "−" は何も実装していないことを表す。

[Note] 注釈

※1.SFYContainer::ScrollUp 関数を実行します。

※2.SFYContainer::ScrollDown 関数を実行します。

※3.SFYContainer::PageUp 関数を実行します。

※4.SFYContainer::PageDown 関数を実行します。

※5.SFYContainer::SnapUp 関数を実行します。

※6.SFYContainer::SnapDown 関数を実行します。

ユーザー定義コンテナを作成するときに最低限必要なコードを示します。

例 9.54. 宣言

SFMTYPEDEFRESPONDER(USRContainer)
class USRContainer: public SFYContainer {
    SFMSEALRESPONDER(USRContainer)
    SFMRESPONDERINSTANTIATETHREE(USRContainer, SFYContainer, SFYWidget, SFYResponder)
public:

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

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

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

例 9.55. 実装

// コンストラクタ
USRContainer::USRContainer(Void) static_throws
{
    if (static_try()) {

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

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

// デストラクタ
USRContainer::~USRContainer(Void)
{
    // 終了処理を記述する
}

// スマートポインタで管理されるインスタンスを生成する関数
USRContainerSmp USRContainer::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRContainer>(Factory(::new USRContainer, exception));
}

Void USRContainer::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // コンテナに最適な大きさを計算して rectangle パラメータに設定する
    // この関数内では、rectangle の原点は変更せず、rectangle のサイズだけを設定する(推奨)

    return;
}

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

    return;
}

Void USRContainer::HandleBoundReal(Void)
{
    // 実領域が変更された場合に再計算が必要なものがあれば、ここに記述する

    return;
}

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

    return;
}

Void USRContainer::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // コンテナを描画する

    return;
}