SophiaFramework UNIVERSE 5.3 |
この節では、 複数のコントロールを同時に使用する方法や、コントロール同士の連携などについて解説します。
SFZTextButtonControl や SFZImageButtonControl などのコントロールでは、 フォーカス状態の場合に描画されるフォーカス枠の色を変更できます。
この機能は、 コントロールがフォーカス状態にあることをより強調する場合や、 インターフェースの全体的な色のセットを変更する場合に利用します。
例 9.141. 宣言
SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow: public SFZWindow {
SFMSEALRESPONDER(USRWindow)
SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
SFZTextButtonControlSmp _button;
// ...(省略)...
private:
SFCError Make(Void);
};
例 9.142. 実装
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->SetText("hello world");
if (error == SFERR_NO_ERROR) {
// デフォルトのフォーカス枠の色を取得し、RGB カラーの赤の要素を加算して設定する
_button->SetFocusColor(SFXBevelColor(_button->GetFocusColor()).AddRed(0xFF));
_button->SetRealBound(_button->GetSuitableBound().SetOrigin(10, 10));
_button->SetState(true, true, true, true);
}
}
}
return error;
}
SFZTextButtonControl や SFZImageButtonControl などのコントロールでは、 フォーカス枠の色に加え、コントロールの各個所の色を変更できます。
変更できる個所は、コントロールの種類や実装に依存します。
例 9.143. 宣言
SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow: public SFZWindow {
SFMSEALRESPONDER(USRWindow)
SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
SFZTextButtonControlSmp _button;
// ...(省略)...
private:
SFCError Make(Void);
};
例 9.144. 実装
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->SetText("hello world"); if (error == SFERR_NO_ERROR) { // デフォルトのフォーカス枠の色を取得し、RGB カラーの赤と緑の要素を減算して設定する _button->SetFocusColor(SFXBevelColor(_button->GetFocusColor()).SubRGB(0x33, 0x33, 0x00)); // デフォルトのボタン色を取得し、RGB カラーの赤と緑の要素を減算して設定する _button->SetButtonColor(SFXBevelColor(_button->GetButtonColor()).SubRGB(0x33, 0x33, 0x00)); _button->SetRealBound(_button->GetSuitableBound().SetOrigin(10, 10)); _button->SetState(true, true, true, true); } } } return error; }
SFZMultipleTextLabelControl や SFZMultipleTextBoxControl などの複数行のテキストを表示するレスポンダでは、 矩形領域の引数を指定しない SFYResponder::GetSuitableBound 関数の振る舞いが他のレスポンダとは異なります。
このレスポンダでは、複数行のテキストを表示するために最適な領域を計算するためのヒント値が必要です。
具体的には、 これらのレスポンダの SFYResponder::GetSuitableBound 関数を呼び出すときに矩形領域の引数を指定しない場合、 SFYResponder::SetRealBound 関数で設定する実領域の横幅がヒント値として利用されます。
注意 | |
---|---|
実領域の横幅(ヒント値)には使用しているフォントの横幅以上の値を設定します。 |
領域計算のヒント値として以下のように利用されます。
SFYResponder::GetSuitableBound 関数で矩形領域の引数を指定する場合、 領域計算をする直前に実領域をヒント値として設定する必要はありません。
表 9.31. 引数を指定せずに GetSuitableBound 関数を呼び出す直前に実領域の横幅を設定する必要のあるレスポンダ
クラス名 | 解説 |
---|---|
SFYMultipleTextWidget | 複数行の編集不可能なテキストを表示するウィジェットです。 |
SFYMultipleEditWidget | 複数行の編集可能なテキストを表示するウィジェットです。 |
SFZMultipleTextLabelControl | 複数行の編集不可能なテキストを表示するラベルコントロールです。 |
SFZMultipleEditLabelControl | 複数行の編集可能なテキストを表示するラベルコントロールです。 |
SFZMultipleTextBoxControl | 複数行の編集不可能なテキストを表示するボックスコントロールです。 |
SFZMultipleEditBoxControl | 複数行の編集可能なテキストを表示するボックスコントロールです。 |
SFZMessageDialog | 通知メッセージを表示するダイアログです。 |
SFZQuestionDialog | 選択メッセージを表示するダイアログです。 |
例 9.145. 宣言
SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow: public SFZWindow {
SFMSEALRESPONDER(USRWindow)
SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
SFZMultipleTextLabelControlSmp _label;
// ...(省略)...
private:
SFCError Make(Void);
};
例 9.146. 実装
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->SetText("hello world\n\n" "0 \n" " 1 \n" " 2 \n" " 3 \n" " 4 \n" " 5 \n" " 6 \n" " 7 \n" " 8 \n" " 9 \n" " 0"); if (error == SFERR_NO_ERROR) { // ヒント値を設定する _label->SetRealBound(GetLocalBound().Deflate(10, 10)); // 矩形を指定せずに最適な大きさを取得して設定する _label->SetRealBound(_label->GetSuitableBound().SetOrigin(10, 10)); _label->SetState(true, true, true, true); } } } return error; }
1 つのコンテナ内に複数のコントロールを配置する場合、 SFYResponder::GetSuitableBound 関数を利用することで見栄えのよいインターフェースを作成できます。
例 9.147. 宣言
SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow: public SFZWindow {
SFMSEALRESPONDER(USRWindow)
SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
SFZTextButtonControlSmp _button;
SFZSingleTextBoxControlSmp _box;
SFZCheckboxControlSmp _checkbox;
// ...(省略)...
private:
SFCError Make(Void);
};
例 9.148. 実装
SFCError USRWindow::Make(Void) { SFXRectangle rectangle; SFCError error(SFERR_NO_ERROR); // 1 つ目のコントロールの左上の座標を設定する rectangle.Set(GetLocalBound().Deflate(10, 10)); // 1 つ目のコントロールを作成する if ((_button = SFZTextButtonControl::NewInstance(&error)) != null) { error = _button->SetParent(GetThis()); if (error == SFERR_NO_ERROR) { error = _button->SetText("first"); if (error == SFERR_NO_ERROR) { _button->SetRealBound(_button->GetSuitableBound(rectangle)); _button->SetState(true, true, true, true); // 2 つ目のコントロールの左上の座標を計算する rectangle.AddY(_button->GetRealBound().GetHeight() + 5); // 2 つ目のコントロールを作成する if ((_box = SFZSingleTextBoxControl::NewInstance(&error)) != null) { error = _box->SetParent(GetThis()); if (error == SFERR_NO_ERROR) { error = _box->SetText("second"); if (error == SFERR_NO_ERROR) { _box->SetRealBound(_box->GetSuitableBound(rectangle)); _box->SetState(true, true, true, false); // 3 つ目のコントロールの左上の座標を計算する rectangle.AddY(_box->GetRealBound().GetHeight() + 5); // 3 つ目のコントロールを作成する if ((_checkbox = SFZCheckboxControl::NewInstance(&error)) != null) { error = _checkbox->SetParent(GetThis()); if (error == SFERR_NO_ERROR) { error = _checkbox->SetText("third"); if (error == SFERR_NO_ERROR) { _checkbox->SetRealBound(_checkbox->GetSuitableBound(rectangle)); _checkbox->SetState(true, true, true, false); // 4 つ目のコントロールの左上の座標を計算する rectangle.AddY(_checkbox->GetRealBound().GetHeight() + 5); // ...(省略)... } } } } } } } } } return error; }
以下のコードでは、 複数のラジオボタンコントロールをグループ化することにより、 排他的なチェック状態の切り替えが自動的に実現されています。
注意 | |
---|---|
自動的な排他処理はユーザーのキー操作によってのみ行われ、 SFYControl::SetCurrentValue 関数を使用してチェック状態を切り替える場合には行われません。 |
例 9.149. 宣言
SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow: public SFZWindow {
SFMSEALRESPONDER(USRWindow)
SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
SFZRadiobuttonControlSmp _radiobutton[5];
// ...(省略)...
private:
SFCError Make(Void);
};
例 9.150. 実装
SFCError USRWindow::Make(Void) { SFXRectangle rectangle; SInt16 i; SFCError error(SFERR_NO_ERROR); rectangle.Set(GetLocalBound().Deflate(10, 10)); // ラジオボタンコントロールをまとめて作成する for (i = 0; i < 5 & error == SFERR_NO_ERROR; ++i) { if ((_radiobutton[i] = SFZRadiobuttonControl::NewInstance(&error)) != null) { error = _radiobutton[i]->SetParent(GetThis()); if (error == SFERR_NO_ERROR) { error = _radiobutton[i]->SetText(SFXWideString::Format("number %d", i)); if (error == SFERR_NO_ERROR) { _radiobutton[i]->SetRealBound(_radiobutton[i]->GetSuitableBound(rectangle)); _radiobutton[i]->SetState(true, true, true, false); rectangle.AddY(_radiobutton[i]->GetRealBound().GetHeight() + 5); } } } } if (error == SFERR_NO_ERROR) { // すべてのラジオボタンコントロールをグループ化する for (i = 1; i < 5; ++i) { _radiobutton[i]->Group(_radiobutton[0]); } // 1 つ目のラジオボタンコントロールをチェックされている状態に設定する _radiobutton[0]->SetCurrentValue(true); // 1 つ目のラジオボタンコントロールにフォーカスを移動する _radiobutton[0]->SetStateFocus(true); } return error; }
以下のコードでは、 チェックボックスコントロールの状態に応じて、 関連するコントロールの活性状態を切り替えることによりユーザービリティの高いインターフェースを実現しています。
例 9.151. 宣言
SFMTYPEDEFRESPONDER(USRWindow) class USRWindow: public SFZWindow { SFMSEALRESPONDER(USRWindow) SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder) private: SFZCheckboxControlSmp _checkbox[2]; SFZRadiobuttonControlSmp _radiobutton[3]; SFZSingleEditBoxControlSmp _editbox; // ...(省略)... private: SFCError Make(Void); SFCError Init(SFYResponderSmpConstRef responder, SFXRectanglePtr rectangle); // 1 つ目のチェックボックスコントロールのチェック変更イベントを受信するハンドラ XANDLER_DECLARE_VOIDVALUE(OnValue0) // 2 つ目のチェックボックスコントロールのチェック変更イベントを受信するハンドラ XANDLER_DECLARE_VOIDVALUE(OnValue1) };
例 9.152. 実装
SFCError USRWindow::Make(Void) { static ACharConst item[][8] = { "Unix", "Mac", "Windows" }; SFXRectangle rectangle; SInt16 i; SFCError error(SFERR_NO_ERROR); rectangle.Set(GetLocalBound().Deflate(10, 10)); if ((_checkbox[0] = SFZCheckboxControl::NewInstance(&error)) != null) { // チェックボックスコントロールのチェック変更イベントを受信するハンドラを登録する error = _checkbox[0]->RegisterHandler( SFXEventRange(SFEVT_RESPONDER_VALUE, SFEVT_RESPONDER_VALUE, SFP16_VALUE_CURRENT, SFP16_VALUE_CURRENT), XANDLER_INTERNAL(OnValue0) ); if (error == SFERR_NO_ERROR) { error = _checkbox[0]->SetText("Use linebreak"); if (error == SFERR_NO_ERROR) { error = Init(_checkbox[0], &rectangle); if (error == SFERR_NO_ERROR) { rectangle.AddLeft(10); for (i = 0; i < 3 & error == SFERR_NO_ERROR; ++i) { if ((_radiobutton[i] = SFZRadiobuttonControl::NewInstance(&error)) != null) { error = _radiobutton[i]->SetText(item[i]); if (error == SFERR_NO_ERROR) { error = Init(_radiobutton[i], &rectangle); } } } for (i = 1; i < 3 & error == SFERR_NO_ERROR; ++i) { _radiobutton[i]->Group(_radiobutton[0]); } rectangle.SubLeft(10); } } } } if (error == SFERR_NO_ERROR) { if ((_checkbox[1] = SFZCheckboxControl::NewInstance(&error)) != null) { // チェックボックスコントロールのチェック変更イベントを受信するハンドラを登録する error = _checkbox[1]->RegisterHandler( SFXEventRange(SFEVT_RESPONDER_VALUE, SFEVT_RESPONDER_VALUE, SFP16_VALUE_CURRENT, SFP16_VALUE_CURRENT), XANDLER_INTERNAL(OnValue1) ); if (error == SFERR_NO_ERROR) { error = _checkbox[1]->SetText("Use suffix"); if (error == SFERR_NO_ERROR) { error = Init(_checkbox[1], &rectangle); if (error == SFERR_NO_ERROR) { rectangle.AddLeft(10); if ((_editbox = SFZSingleEditBoxControl::NewInstance(&error)) != null) { error = _editbox->SetText(".txt"); if (error == SFERR_NO_ERROR) { error = Init(_editbox, &rectangle); } } rectangle.SubLeft(10); } } } } } if (error == SFERR_NO_ERROR) { // 初期状態を調整する _checkbox[0]->SetCurrentValue(true); _radiobutton[0]->SetCurrentValue(true); _checkbox[1]->SetCurrentValue(true); _checkbox[0]->SetStateFocus(true); } return error; } SFCError USRWindow::Init(SFYResponderSmpConstRef responder, SFXRectanglePtr rectangle) { SFCError error(SFERR_NO_ERROR); error = responder->SetParent(GetThis()); if (error == SFERR_NO_ERROR) { responder->SetRealBound(responder->GetSuitableBound(*rectangle)); responder->SetState(true, true, true, false); rectangle->AddY(responder->GetRealBound().GetHeight() + 5); } return error; } XANDLER_IMPLEMENT_VOIDVALUE(USRWindow, OnValue0, invoker, reason, value) { SInt16 i; // チェックボックスコントロールの状態に応じて、 // 活性状態を切り替える for (i = 0; i < 3; ++i) { _radiobutton[i]->SetStateActive(value != 0); } return; } XANDLER_IMPLEMENT_VOIDVALUE(USRWindow, OnValue1, invoker, reason, value) { // チェックボックスコントロールの状態に応じて、 // 活性状態を切り替える _editbox->SetStateActive(value != 0); return; }
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |