![]() ![]() ![]()
|
BREW C++ ライブラリ & GUI フレームワーク & XML ミドルウェア : SophiaFramework UNIVERSE 5.0 |
複数のコントロールを同時に使用する方法や、コントロール同士の連携などについて解説します。
各種コントロールでは、フォーカス状態の場合に描画されるフォーカスの色を変更できます。
フォーカスを目立たせたい場合やインターフェース全体の色を変更する場合などに利用できます。
例 9.125. 宣言
SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
SFMSEALRESPONDER(USRWindow)
SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
SFZTextButtonControlSmp _button;
...
private:
SFCError Make(Void);
};
例 9.126. 実装
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) {
// デフォルトのフォーカス色を取得し、赤色を加算して設定する
_button->SetFocusColor(SFXBevelColor(_button->GetFocusColor()).AddRed(0xFF));
_button->SetRealBound(_button->GetSuitableBound().SetOrigin(10, 10));
_button->SetState(true, true, true, true);
}
}
}
return error;
}
各種コントロールでは、フォーカスの色に加え、コントロールの各個所の色を変更できます。
変更できる個所は、コントロールの種類や実装に依存します。
例 9.127. 宣言
SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
SFMSEALRESPONDER(USRWindow)
SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
SFZTextButtonControlSmp _button;
...
private:
SFCError Make(Void);
};
例 9.128. 実装
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) {
// デフォルトのフォーカス色を取得し、赤色と緑色を減算して設定する
_button->SetFocusColor(SFXBevelColor(_button->GetFocusColor()).SubRGB(0x33, 0x33, 0x00));
// デフォルトのボタン色を取得し、赤色と緑色を減算して設定する
_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 関数のうち、引数の矩形を指定しない関数が例外的な動作を行います。
これらのクラスでは複数行のテキストを表示するために、高さまたは幅のどちらかを固定しなければ最適な大きさを求められません。そこで、設定されている実領域の幅をヒント値として利用し最適な大きさを計算します。
引数を指定する関数では通常の動作を行い、実領域をあらかじめ設定する必要はありません。
引数を指定する関数と指定しない関数では、指定した矩形で高さを制限するかしないかの違いがあります。
例 9.129. 宣言
SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
SFMSEALRESPONDER(USRWindow)
SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
SFZMultipleTextLabelControlSmp _label;
...
private:
SFCError Make(Void);
};
例 9.130. 実装
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.131. 宣言
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.132. 実装
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.133. 宣言
SFMTYPEDEFRESPONDER(USRWindow)
class USRWindow : public SFZWindow {
SFMSEALRESPONDER(USRWindow)
SFMRESPONDERINSTANTIATEFOUR(USRWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
private:
SFZRadiobuttonControlSmp _radiobutton[5];
...
private:
SFCError Make(Void);
};
例 9.134. 実装
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.135. 宣言
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.136. 実装
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 - 2008 Sophia Cradle Incorporated All Rights Reserved. |
![]() ![]() ![]()
|