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

9.1. レスポンダシステムの概要

SophiaFramework UNIVERSE レスポンダシステム(以下、「レスポンダシステム」と呼ぶ)とは、 SophiaFramework UNIVERSE に含まれる GUI フレームワークを構成する SFY または SFZ で始まる名前のクラス群の総称です。

レスポンダシステムには、イベントを配信するための配信エンジンと、 画面に GUI コンポーネントを描画するための描画エンジンが搭載され、 ウィンドウ、ダイアログ、メニュー、ボタンやラベル、タブなどのコントロールという標準的な GUI コンポーネントも提供されます。

レスポンダシステムを利用すれば、 複雑なイベントの分岐処理を記述したり、 GUI コンポーネントを描画したり、 GUI コンポーネントの状態やメモリを管理する必要はありません。

そのため、複雑なユーザーインターフェースを持つアプレットでも簡単にすぐ作成できます。

[Note] レスポンダ

レスポンダシステムでは、GUI コンポーネントのことをレスポンダと呼びます。

9.1.1. レスポンダシステムとは

レスポンダシステムとは、 レスポンダと呼ぶウィンドウメニューダイアログコントロールフレームなどの GUI コンポーネントを画面上に配置するだけで、 イベントの分岐や、画面の描画を自動的に行ってくれる GUI フレームワークのことです。

レスポンダシステムを利用すれば、 下記のような複雑な処理やプログラミングをする必要がなくなるので、 アプレット開発・保守の生産性は著しく向上します。

■レスポンダシステムの主な機能

  1. イベントの分岐処理
  2. レスポンダの描画処理
  3. レスポンダの状態管理
  4. レスポンダのメモリ管理
  5. ウィンドウ、ダイアログ、メニュー、コントロール、フレームなどカスタマイズ可能な汎用レスポンダ

表 9.1. 主な SophiaFramework UNIVERSE 標準提供汎用レスポンダ

クラス名 解説
SFYApplication レスポンダシステムを利用するアプレットのアプリケーションクラスの雛型です。
SFYResponder すべてのレスポンダはこのクラスを継承します。 すべてのレスポンダに共通する機能が実装されています。 一般的なアプレット開発では、このクラスを直接利用することはほとんどありません。
SFZRoot ウィンドウ、ダイアログやメニューなどを配置する汎用ルートです。
SFZContainer コントロールやコンテナなどを配置する汎用コンテナです。
SFZWindow コントロールやコンテナなどを配置する汎用ウィンドウです。
SFZDialog コントロールやコンテナなどを配置する汎用ダイアログです。
SFZMessageDialog 通知メッセージを表示するダイアログです。
SFZQuestionDialog 選択メッセージを表示するダイアログです。
SFZGridMenu グリッドメニューです。
SFZTextMenu テキストメニューです。
SFZSingleTextLabelControl 単一行の編集不可能なテキストを表示するラベルコントロールです。
SFZSingleEditLabelControl 単一行の編集可能なテキストを表示するラベルコントロールです。
SFZMultipleTextLabelControl 複数行の編集不可能なテキストを表示するラベルコントロールです。
SFZMultipleEditLabelControl 複数行の編集可能なテキストを表示するラベルコントロールです。
SFZImageLabelControl イメージを表示するラベルコントロールです。
SFZSingleTextBoxControl 単一行の編集不可能なテキストを表示するボックスコントロールです。
SFZSingleEditBoxControl 単一行の編集可能なテキストを表示するボックスコントロールです。
SFZMultipleTextBoxControl 複数行の編集不可能なテキストを表示するボックスコントロールです。
SFZMultipleEditBoxControl 複数行の編集可能なテキストを表示するボックスコントロールです。
SFZImageBoxControl イメージを表示するボックスコントロールです。
SFZTextButtonControl テキストを表示するボタンコントロールです。
SFZImageButtonControl イメージを表示するボタンコントロールです。
SFZComboBoxControl コンボボックスコントロールです。
SFZListBoxControl リストボックスコントロールです。
SFZCheckboxControl チェックボックスコントロールです。
SFZRadiobuttonControl ラジオボタンコントロールです。
SFZTabControl タブコントロールです。
SFZTabPage タブコントロールのタブページです。
SFZScrollBarControl スクロールバーコントロールです。
SFZBandScrollBarControl 帯コントロール用のスクロールバーコントロールです。
SFZSoftKeyControl ソフトキー コントロールです。
SFZWebBrowserControl 簡易ウェブブラウザコントロールです。
SFZPlainFrame プレーンフレームです。
SFZFlatFrame フラットフレームです。
SFZBevelFrame ベベルフレームです。
SFZTitlePlainFrame タイトル付きプレーンフレームです。
SFZTitleFlatFrame タイトル付きフラットフレームです。
SFZTitleBevelFrame タイトル付きベベルフレームです。
[Note] SophiaFramework UNIVERSE 標準提供レスポンダ一覧

レスポンダシステムには、 上の表にあるクラス以外に独自のレスポンダを作成するための起点となる、SFY で始まる名前の抽象クラスも含まれています。

SophiaFramework UNIVERSE が標準提供するレスポンダの一覧は、 カテゴリ別クラスリファレンス : SFY レスポンダシステムをご覧ください。

[Important] SFYResponder と SFYApplication について

ウィンドウメニューダイアログコントロールルートフレームなど、 すべてのレスポンダは SFYResponder クラスを継承します。

SFYApplication クラスは SFYResponder クラスを継承しません。 SFYApplication クラスは、 デフォルトでルート(SFZRoot)を保持し、 ルートがレスポンダの所有関係の起点となります。 SFYApplication クラスに対するレスポンダ操作はすべてルートに委譲されます。

9.1.2. レスポンダシステムの使い方

レスポンダシステムを利用するには、 最初に SFYApplication クラスを継承したアプリケーションクラスを1つ用意する必要があります。

SophiaFramework UNIVERSE AppWizard を利用してプロジェクトを作成する場合は、 GUI フレームワークの選択画面で「使用する(SFY バージョン)」オプションを選択すると、 SFYApplication クラスを継承したアプリケーションクラスが自動的1つ生成されます。

アプリケーションクラス名は、通常 HelloWorld や USRApplication などアプレット本体と同じ名前になります。

[Caution] 大文字アルファベットを含むアプリケーションクラス名(BREW 4.0のみ)

通常、HelloWorld などのアプリケーションクラスの名前はアプレット本体と同じ名前にします。

BREW 4.0 からアプレットの名前に大文字アルファベットが使えなくなりました。

HelloWorld や USRApplication などアプリケーションクラスの名前に大文字アルファベットを使う場合、 大文字アルファベットを小文字アルファベットに変換する必要があります。

次に、作成したアプリケーションクラスにウィンドウを作成するには以下のように記述します。

例 9.1. ウィンドウの作成

SFCError USRApplication::Window(Void)
{
    SFZWindowSmp window;
    SFCError error(SFERR_NO_ERROR);

    ...

    // ウィンドウのインスタンを生成する
    if ((window = SFZWindow::NewInstance(&error)) != null) {
        // ウィンドウの親レスポンダをアプリケーションクラス(USRApplication)に設定する
        error = window->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {
            // ウィンドウの実領域を携帯電話画面から(10, 10)だけ Deflate した矩形に設定する
            window->SetRealBound(window->GetSuitableBound(GetLocalBound().Deflate(10, 10)));
            // ウィンドウの状態を「可視+活性+操作可能+フォーカス」にまとめて設定する
            window->SetState(true, true, true, true);
            // ウィンドウを最前面に配置する
            window->ToFront();
        }
    }

    ...
}
[Tip] ウィンドウの作成に必要な処理
  1. SFZWindow::NewInstance 関数を呼び出してウィンドウ(SFZWindow)のインスタンスを生成します。
  2. SFYResponder::SetParent 関数を呼び出して既に配置されているレスポンダを親レスポンダとして設定します。
  3. SFYResponder::SetRealBound 関数を呼び出して親レスポンダのローカル領域内での自レスポンダの実領域を設定します。
  4. SFYResponder::SetState 関数を呼び出して自レスポンダの状態を設定します。
  5. SFYResponder::ToFront 関数を呼び出して子レスポンダと一緒に自レスポンダを最前面に配置します。

参照 : SFZWindow | SFYResponder::GetThis | SFYResponder::GetSuitableBound | SFYResponder::GetLocalBound | SFXRectangle::Deflate

そして、 ウィンドウの上にボタンコントロールを配置するには次のように記述します。

例 9.2. ボタンコントロールの作成

SFCError USRApplication::MakeButtonControl(Void)
{
    SFZWindowSmp window;
    SFZTextButtonControlSmp button;
    SFCError error(SFERR_NO_ERROR);

    ...

    // ボタンコントロールのインスタンスを生成する
    if ((button = SFZTextButtonControl::NewInstance(&error)) != null) {
        // ボタンコントロールの親レスポンダをウィンドウに設定する
        error = button->SetParent(window);
        if (error == SFERR_NO_ERROR) {
            // ボタンコントロールのラベルを "hello world" に設定する
            error = button->SetText("hello world");
            if (error == SFERR_NO_ERROR) {
                // ウィンドウのローカル領域からボタンコントロールを表示するのに最適なサイズを確保し、開始点を(10, 10)に設定する
                button->SetRealBound(button->GetSuitableBound().SetOrigin(10, 10));
                // ボタンコントロールの状態を「可視+活性+操作可能+フォーカス」にまとめて設定する
                button->SetState(true, true, true, true);
            }
        }
    }

    ...
}
[Tip] ボタンコントロールの作成に必要な処理
  1. SFZTextButtonControl::NewInstance 関数を呼び出してテキストボタンコントロール(SFZTextButtonControl)のインスタンスを生成します。
  2. SFYResponder::SetParent 関数を呼び出して既に配置されているレスポンダを親レスポンダとして設定します。
  3. SFZTextButtonControl::SetText 関数を呼び出してラベル項目を設定します。
  4. SFYResponder::SetRealBound 関数を呼び出して親レスポンダのローカル領域内での自レスポンダの実領域を設定します。
  5. SFYResponder::SetState 関数を呼び出して自レスポンダの状態を設定します。
[Important] ToFront() 関数

コントロールは配置されるウィンドウやダイアログ、コンテナなどの親レスポンダが最前面に来ない限り、最前面に配置されません。

親レスポンダの SFYResponder::ToFront 関数を呼び出すことにより、コントロールは自動的に最前面に配置されます。

参照 : SFZWindow | SFZTextButtonControl | SFYResponder::GetSuitableBound | SFXRectangle::SetOrigin

ボタンコントロールを操作するとデバッグ出力に文字列を表示するコードは以下のとおりです。

例 9.3. ボタンコントロールの応答

SFZTextButtonControlSmp button;
SFCError error(SFERR_NO_ERROR);

...

// ボタンコントロール button のハンドラ OnResult を登録する
error = button->RegisterHandler(
    SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
    XANDLER_INTERNAL(OnResult)
);
...


// ボタンコントロール button のハンドラ OnResult の実装
XANDLER_IMPLEMENT_VOIDRESULT(USRApplication, OnResult, invoker, reason, result)
{
    // デバッグウィンドウに "button was pushed." と表示する
    TRACE("button was pushed.");
    return;
}
[Note] ハンドラの登録と実装

ボタンコントロールが操作されると、結果イベントが発生するので、 SFYApplication::RegisterHandler 関数を利用して結果イベントのハンドラをボタンコントロールに登録します。

結果イベントのハンドラは、XANDLER_DECLARE_VOIDRESULT マクロを利用して実装します。

以上のようにウィンドウの上にボタンコントロールなどのコントロールを配置し、 コントロールが操作されたときに呼び出されるハンドラを登録し実装するだけで、 GUI を持つアプレットを簡単にすぐ作成できます。

9.1.3. レスポンダシステムの構造

SFYApplication を継承したアプリケーションクラスは、 ウィンドウメニューダイアログコントロールフレームなどのレスポンダを管理する起点となります。

レスポンダシステムでは アプリケーションクラスがデフォルトでルート(SFZRoot)を保持し、 ルートがウィンドウ、メニュー、またはダイアログを、 ウィンドウやダイアログがコントロールを管理するという階層構造になっています。

ダイアログとメニューはウィンドウと同一階層に存在します。

コンテナはコントロールや 他のコンテナ(コンテナのみ)を管理したり、コントロールや他のコンテナ(コンテナ・ウィンドウ・ダイアログ)に管理されることが可能な変則的な設計になっています。

[Important] フレームについて

ウィンドウ、メニュー、ダイアログなどのレスポンダには、タイトルや余白を持つ枠組み(フレーム)を付けることが可能です。

このとき、これらのレスポンダの親はフレームとなり、フレームがウィンドウ、メニュー、ダイアログなどのレスポンダを管理します。

[Note] アプリケーションクラス=ルート

アプリケーションクラスはレスポンダではありませんが、 ルート(SFZRoot)と呼ぶレスポンダをデフォルトで1つ保持しています。

そのため、 差し障りがなければアプリケーションクラスをルートとして扱って解説している箇所がいくつかあります。

図 9.1. 所有関係

所有関係

ウィンドウメニューダイアログコントロールなど、 すべてのレスポンダクラスは SFYResponder を継承します。

図 9.2. 継承関係

継承関係