SophiaFramework UNIVERSE 5.3 |
下図の汎用コンテナ(SFZContainer)を作成します。
コードの概要は以下の通りです。
コンテナ | |
---|---|
コンテナは、コントロールや他のコンテナ(コンテナ・ウィンドウ・ダイアログ)を配置するように設計されたレスポンダです。 ウィンドウやダイアログもコンテナの一種です。 コンテナのなかにコントロールやコンテナなどのレスポンダが配置されている場合、 SFYContainer::SetScrollDownKey / SFYContainer::SetScrollUpKey / SFYContainer::SetPageDownKey / SFYContainer::SetPageUpKey / SFYContainer::SetSnapDownKey / SFYContainer::SetSnapUpKey 関数で設定するスクロールキーを使用してレスポンダ間でフォーカスを移動できます。 仮想領域が実領域よりも大きい場合は、 フォーカス移動機能と連動した、 仮想領域の上下方向へのスクロール機能も利用できます。 |
ItsWindow を定義します。
例 3.51. ItsWindow クラスの定義
// ItsWindow クラスの定義 SFMTYPEDEFRESPONDER(ItsWindow) // 便利な型を生成するマクロ class ItsWindow : public SFZWindow { SFMSEALRESPONDER(ItsWindow) // インスタンスのコピーを禁止するマクロ // SFYResponder からこのクラスに至るまでの継承順序を指定するマクロ SFMRESPONDERINSTANTIATEFOUR(ItsWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder) public: // 小文字アルファベットまたは記号 4 文字からなるタイプは予約されているので // ItsWindow のタイプを大文字アルファベット('I', 'W', 'N', 'D')で定義する enum CodeEnum { CODE_TYPE = four_char_code('I', 'W', 'N', 'D') }; SFMTYPEDEFTYPE(CodeEnum) public: static ItsWindowSmp NewInstance(SFCErrorPtr exception = null); // ItsWindow 上の各種コンテナおよびコントロールを作成する関数 SFCError Make(Void); protected: explicit ItsWindow(Void) static_throws; virtual ~ItsWindow(Void); private: // キーハンドラ XANDLER_DECLARE_BOOLEVENT(OnKey) }; // 配色定義 #define COLOR_ITS_WINDOW_BACK (SFXRGBColor(0xCC, 0xFF, 0xCC, 0x00)) // コンストラクタ ItsWindow::ItsWindow(Void) static_throws { if (static_try()) { SetType(CODE_TYPE); // ItsWindow のキーハンドラを登録する static_throw(RegisterHandler( SFXEventRange(SFEVT_KEY, SFEVT_KEY, SFP16_BEGIN, SFP16_END), XANDLER_INTERNAL(OnKey) )); // ItsWindow の背景色を薄緑色にする SetBackgroundColor(COLOR_ITS_WINDOW_BACK); } } // デストラクタ ItsWindow::~ItsWindow(Void) { } // ItsWindow インスタンスを生成する NewInstance 関数 ItsWindowSmp ItsWindow::NewInstance(SFCErrorPtr exception) { return static_pointer_cast<ItsWindow>(Factory(:: new ItsWindow, exception)); } // ItsWindow 上の各種コンテナおよびコントロールを作成する関数 SFCError ItsWindow::Make(Void) { SFYContainerSmp container; SFZContainerScrollBarControlSmp bar; SFCError error(SFERR_NO_ERROR); // 汎用コンテナを作成する if ((container = SFZContainer::NewInstance(&error)) != null) { // コンテナの親をウィンドウに設定する if ((error = container->SetParent(GetThis())) == SFERR_NO_ERROR) { // 実領域をウィンドウのローカル領域から(5, 5, 10, 5)だけ Deflate した領域に設定する container->SetRealBound(GetLocalBound().Deflate(5, 5, 10, 5)); // 仮想領域を実領域より下に 150 だけ伸張する container->SetVirtualBound(SFXRectangle(container->GetRealBound()).AddHeight(150)); // コンテナの状態を「可視+活性+操作可能+フォーカス」にまとめて設定する container->SetState(true, true, true, true); SFZTextButtonControlSmp button; // ボタンコントロールを作成する if ((button = SFZTextButtonControl::NewInstance(&error)) != null) { // ボタンコントロールの親をコンテナに設定する if ((error = button->SetParent(container)) == SFERR_NO_ERROR) { // ボタンコントロールの文字列を "CenterMiddle" に設定する if ((error = button->SetText("CenterMiddle")) == SFERR_NO_ERROR) { // ボタンコントロールをコンテナのローカル領域の中央に配置する button->SetRealBound(button->GetSuitableBound(container->GetLocalBound()).SnapCenterMiddle(container->GetLocalBound().GetCenterMiddle())); // ボタンコントロールの状態を「可視+活性+操作可能+フォーカス」にまとめて設定する button->SetState(true, true, true, true); } } } } } if (error == SFERR_NO_ERROR) { // コンテナ専用のスクロールバーコントロールを作成する if ((bar = SFZContainerScrollBarControl::NewInstance(&error)) != null) { // 親をウィンドウに設定する if ((error = bar->SetParent(GetThis())) == SFERR_NO_ERROR) { // コンテナの右隣にスクロールバーコントロールを配置する // * スクロールバーの幅は 5 SFXRectangle rx; rx.Set(container->GetRealBound()); rx.AddX(rx.GetWidth()); rx.SetWidth(5); bar->SetRealBound(rx); // スクロールバーコントロールの状態を 「可視+活性+操作不能+非フォーカス」にまとめて設定する // * この状態設定により、スクロールバーコントロールにフォーカスが移動することはない bar->SetState(true, true, false, false); /// スクロールバーコントロールをコンテナに結びつける error = bar->Bind(container); } } } return error; } // ItsWindow のキーハンドラの実装 XANDLER_IMPLEMENT_BOOLEVENT(ItsWindow, OnKey, invoker, event) { unused(invoker); Bool result(false); switch (event.GetP16()) { // クリアキーの SFEVT_KEY イベントを受信したとき case AVK_CLR: // ItsWindow を終了する Terminate(); result = true; break; } return result; }
初期画面で 3 キーが押されると、 ItsWindow を表示するようにします。
例 3.52. helloworld アプリケーションクラスにおける ItsWindow の作成
// helloworld アプリケーションクラスの定義 SFMTYPEDEFCLASS(helloworld) // 便利な型を生成するマクロ class helloworld : public SFYApplication { SFMSEALCOPY(helloworld) // インスタンスのコピーを禁止するマクロ private: MyWindowSmp _myWindow; SFZTextMenuSmp _textMenu; // *** 太字が追加部分 // ItsWindow のスマートポインタ ItsWindowSmp _itsWindow; public: static SFCInvokerPtr Factory(Void); private: explicit helloworld(Void) static_throws; virtual ~helloworld(Void); SFCError MakeMy(Void); SFCError MakeMenu(Void); SFCError MakeColorDialog(UserColorConstRef color); // ItsWindow 作成 SFCError MakeIts(Void); Void SetMenuColors(UserColorConstRef color); XANDLER_DECLARE_VOIDRENDER(OnRenderRequest) // 描画ハンドラ XANDLER_DECLARE_BOOLEVENT(OnKey) // キーハンドラ XANDLER_DECLARE_VOIDRESULT(OnMenuResult) // 結果ハンドラ }; // ItsWindow を作成する関数 SFCError helloworld::MakeIts(Void) { SFCError error(SFERR_NO_ERROR); // ItsWindow インスタンスを作成する if ((_itsWindow = ItsWindow::NewInstance(&error)) != null) { // ItsWindow の親をルートに設定する error = _itsWindow->SetParent(GetThis()); if (error == SFERR_NO_ERROR) { // ItsWindow の実領域を携帯電話画面から(10, 10)だけ Deflate した領域に設定する _itsWindow->SetRealBound(GetLocalBound().Deflate(10, 10)); // ItsWindow の状態を「可視+活性+操作可能+フォーカス」にまとめて設定する _itsWindow->SetState(true, true, true, true); // ItsWindow を最前面に移動する _itsWindow->ToFront(); // ItsWindow のコントロールを作成する _itsWindow->Make(); } } return error; } // helloworld アプリケーションクラスの描画ハンドラの実装 XANDLER_IMPLEMENT_VOIDRENDER(helloworld, OnRenderRequest, invoker, reason, graphics) { unused(invoker); unused(reason); // helloworld アプリケーションクラス(ルート)のローカル領域(携帯電話の画面)の背景は // SetBackgroundColor 関数で設定した色(デフォルト: 白色)で塗り潰される // テキストを描画する graphics->DrawSingleText("Key 1 - Controls", SFXGrid(20, 20), GetLocalBound(), COLOR_BLACK); graphics->DrawSingleText("Key 2 - TextMenu", SFXGrid(20, 40), GetLocalBound(), COLOR_BLACK); graphics->DrawSingleText("Key 3 - Container", SFXGrid(20, 60), GetLocalBound(), COLOR_BLACK); return; } // helloworld アプリケーションクラスのキーハンドラの実装 XANDLER_IMPLEMENT_BOOLEVENT(helloworld, OnKey, invoker, event) { unused(invoker); Bool result(false); if (this->GetChildFront(true, false, false, false) == null) { switch (event.GetP16()) { case AVK_SELECT: // セレクトキーの SFEVT_KEY イベントを受信したとき Terminate(); result = true; break; case AVK_1: // 1 キーの SFEVT_KEY イベントを受信したとき TRACE("key 1"); if (MakeMy() == SFERR_NO_ERROR) { result = true; } break; case AVK_2: // 2 キーの SFEVT_KEY イベントを受信したとき TRACE("key 2"); if (MakeMenu() == SFERR_NO_ERROR) { result = true; } break; case AVK_3: // 3 キーの SFEVT_KEY イベントを受信したとき TRACE("key 3"); // ItsWindow を作成する if (MakeIts() == SFERR_NO_ERROR) { result = true; } break; } } return result; }
参照: コンテナ(基礎編)
下図の枠付きのカスタムコンテナ CustomContainer を定義します。
注意 | |
---|---|
枠はコンテナの実領域(可視領域)の境界上に黒色の点線で描画されます。 |
SFYContainer(抽象コンテナ)を継承するカスタムコンテナ CustomContainer を定義します。
例 3.53. CustomContainer クラスの定義
// CustomContainer クラスの定義 SFMTYPEDEFRESPONDER(CustomContainer) // 便利な型を生成するマクロ class CustomContainer : public SFYContainer { SFMSEALRESPONDER(CustomContainer) // インスタンスのコピーを禁止するマクロ // SFYResponder からこのクラスに至るまでの継承順序を指定するマクロ SFMRESPONDERINSTANTIATETHREE(CustomContainer, SFYContainer, SFYWidget, SFYResponder) public: // 小文字アルファベットまたは記号 4 文字からなるタイプは予約されているので // CustomContainer のタイプを大文字アルファベット('C', 'C', 'T', 'N')で定義する enum CodeEnum { CODE_TYPE = four_char_code('C', 'C', 'T', 'N') }; SFMTYPEDEFTYPE(CodeEnum) public: static CustomContainerSmp NewInstance(SFCErrorPtr exception = null); protected: explicit CustomContainer(Void) static_throws; virtual ~CustomContainer(Void); // 描画ハンドラ virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const; }; // コンストラクタ CustomContainer::CustomContainer(Void) static_throws { if (static_try()) { SetType(CODE_TYPE); } } // デストラクタ CustomContainer::~CustomContainer(Void) { } // CustomContainer インスタンスを生成する NewInstance 関数の実装 CustomContainerSmp CustomContainer::NewInstance(SFCErrorPtr exception) { return static_pointer_cast<CustomContainer>(Factory(:: new CustomContainer, exception)); } // CustomContainer の描画ハンドラの実装 Void CustomContainer::HandleRenderRequest(SFXGraphicsPtr graphics) const { AEEStrokeStyle style; // 線種 // 描画前の線種を記憶しておく style = graphics->GetStrokeStyle(); // 線種を点線に設定する graphics->SetStrokeStyle(STROKE_DOTTED); // CustomContainer のローカル領域からみた実際に描画される領域(可視領域)を計算する // 可視領域は仮想領域と原点を 0 とする実領域サイズの領域との重なり部分になる // また、描画はローカル領域上に行われるため、可視領域のグリッド座標は、 // 仮想領域のグリッド座標をマイナスにした値となる SFXRectangle rx; rx.Set(GetVirtualBound()); rx.Set(SFXGrid(-rx.GetX(), -rx.GetY()), GetRealBound().GetSize()); // 可視領域境界上に黒色の点線を描画する graphics->DrawRectangle(rx, COLOR_BLACK); // 線種を元に戻す graphics->SetStrokeStyle(style); return; }
汎用コンテナ(SFZContainer)をカスタムコンテナ CustomContainer に置き換えます。
注意 | |
---|---|
簡略化のため、 ここではボタンコントロールはコンテナ内に配置していません。 |
例 3.54.
// ItsWindow 上のコンテナとスクロールバーを作成する関数 SFCError ItsWindow::Make(Void) { SFYContainerSmp container; SFZContainerScrollBarControlSmp bar; SFCError error(SFERR_NO_ERROR); // *** 太字が修正部分 // カスタムコンテナを作成する if ((container = CustomContainer::NewInstance(&error)) != null) { // コンテナの親をウィンドウに設定する if ((error = container->SetParent(GetThis())) == SFERR_NO_ERROR) { // 実領域をウィンドウのローカル領域から(5, 5, 10, 5)だけ Deflate した領域に設定する container->SetRealBound(GetLocalBound().Deflate(5, 5, 10, 5)); // 仮想領域を実領域より下に 150 だけ伸張する container->SetVirtualBound(container->GetLocalBound().AddHeight(150)); // コンテナの状態を「可視+活性+操作可能+フォーカス」にまとめて設定する container->SetState(true, true, true, true); // 前節のボタンコントロールは配置しない // } } if (error == SFERR_NO_ERROR) { // スクロールバーコントロール(コンテナ専用)を作成する // ...(省略)... } return error; }
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |