PrevNextUpHome SophiaFramework UNIVERSE 5.3

9.18. Control(Basic)

Control is the responder designed to be placed in a responder such as a container or a window.

SFYControl is the abstract base class for all controls.

Each control has a maximum value, a minimum value, and a current value, whose contents vary from control to control.

The concrete control is the part class which can be used as it is in the applet development. On the other hand, the abstract control is the base class to define and implement the user-defined control.

Table 9.22. Type of concrete control

Class name Description
SFZSingleTextLabelControl Label control to display a single uneditable text.
SFZSingleEditLabelControl Label control to display a single editable text.
SFZMultipleTextLabelControl Label control to display a multiple uneditable text.
SFZMultipleEditLabelControl Label control to display a multiple editable text.
SFZImageLabelControl Label control to display an image.
SFZSingleTextBoxControl Box control to display a single uneditable text.
SFZSingleEditBoxControl Box control to display a single editable text.
SFZMultipleTextBoxControl Box control to display a multiple uneditable text.
SFZMultipleEditBoxControl Box control to display a multiple editable text.
SFZImageBoxControl Box control to display an image.
SFZTextButtonControl Button control to display a text.
SFZImageButtonControl Button control to display an image.
SFZComboBoxControl Combo box control.
SFZListBoxControl List box control.
SFZCheckboxControl Check box control.
SFZRadiobuttonControl Radio button control.
SFZTabControl Tab control.
SFZTabPage Tab page for tab control.
SFZWebBrowserControl Simple web browser control.
SFZScrollBarControl Scroll bar control.
SFZContainerScrollBarControl Scroll bar control for container.
SFZSoftKeyControl SoftKey control.
[Important] IMPORTANT

In the concrete control, the SFYResponder::SetParent, SFYResponder::SetState, and SFYResponder::SetRealBound functions must be always called.

Other functions are optionally called.

Table 9.23. Type of abstract control

Class name Description
SFYControl Abstract class which represents a control.
SFYLabelControl Abstract class which represents a label control.
SFYBoxControl Abstract class which represents a box control.
SFYButtonControl Abstract class which represents a button control.
SFYCheckboxControl Abstract class which represents a check box control.
SFYRadiobuttonControl Abstract class which represents a radio button control.
SFYTabControl Abstract class which represents a tab control.
SFYScrollBarControl Abstract class which represents a scroll bar control.

9.18.1. Label Control to Display a Single Uneditable Text [SFZSingleTextLabelControl]

Figure 9.50. Execution Result(Left: Unenable Mode, Right: Enable Mode)

Execution Result(Left: Unenable Mode, Right: Enable Mode)

There are 2 types of modes (i.e., "enable" and "disable") in a label control to display a single uneditable text(SFZSingleTextLabelControl) depending on its enable state.

In the "enable" mode(when the state is enable), this control can be focused. In the focused state, it will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue())] if the operation key set with the SFYLabelControl::SetOperateKey function is pressed. If there are more characters than can be displayed in the label area of a label control, this control will start to scroll automatically when it is in the focused state.

[Note] Note
This result event will occur in the SFZSingleTextLabelControl::HandleOperateKey function.

This control will behave as a normal label control in the "disable" mode(when the state is disable).

Reference: State | Result Event[SFEVT_RESPONDER_RESULT]

Example 9.84. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler when the operation key is pressed in "enable" mode
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.85. Implementation

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

    // create single text label control
    if ((_label = SFZSingleTextLabelControl::NewInstance(&error)) != null) {

        // set single text label control's parent responder to USRWindow
        error = _label->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler when the operation key is pressed in "enable" mode
            // in case of "disable" mode, it means nothing to register handler because it will not be booted up
            error = _label->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set the text to be displayed
                // * SFXWideString text can be set from the resource file
                error = _label->SetText("hello world");
                if (error == SFERR_NO_ERROR) {

                    // set single text label control's real region to suitable size rectangle [origin=(10, 10)]
                    _label->SetRealBound(_label->GetSuitableBound().SetOrigin(10, 10));

                    // to set "enable" mode to "ON", set all states to "true"
                    _label->SetState(true, true, true, true);
                    // to set "disable" mode to "ON", set enable state to "false"
                    // _label->SetState(true, true, false, false);
                }
            }
        }
    }

    return error;
}

// result handler when the operation key is pressed in "enable" mode
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // single text label control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

    ...

    return;
}

9.18.2. Label Control to Display a Single Editable Text [SFZSingleEditLabelControl]

Figure 9.51. Execution Result(Standard Input Mode)

Execution Result(Standard Input Mode)

Figure 9.52. Execution Result(Password Input Mode)

Execution Result(Password Input Mode)

There are 2 types of modes (i.e., "enable" and "disable") in a label control to display a single editable text(SFZSingleEditLabelControl) depending on its enable state.

In the "enable" mode(when the state is enable), this control can be focused. In the focused state, it will transit to the text input screen if the operation key set with the SFYLabelControl::SetOperateKey function is pressed. After text input, it will then receive the the result event [if text input succeeds, SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue()), otherwise SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_ERROR, Error Value)]. If there are more characters than can be displayed in the label area of a label control, this control will start to scroll automatically when it is in the focused state.

[Note] Note
This result event will occur in the SFZSingleEditLabelControl::HandleOperateKey function.

This control will behave as a normal label control in the "disable" mode(when the state is disable).

Reference: State | Result Event[SFEVT_RESPONDER_RESULT]

Example 9.86. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler after text input in "enable" mode
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.87. Implementation

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

    // create single edit label control
    if ((_label = SFZSingleEditLabelControl::NewInstance(&error)) != null) {

        // set single edit label control's parent responder to USRWindow
        error = _label->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler after text input in "enable" mode
            // in case of "disable" mode, it means nothing to register handler because it will not be booted up
            error = _label->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set number input mode to "ON"
                _label->SetInputMode(AEE_TM_NUMBERS);

                // set password input mode to "ON"
                error = _label->SetPasswordMode(true);
                if (error == SFERR_NO_ERROR) {

                    // set the text to be displayed
                    // * SFXWideString text can be set from the resource file
                    error = _label->SetText("0123456789");
                    if (error == SFERR_NO_ERROR) {

                        // set single edit label control's real region to suitable size rectangle [origin=(10, 10)]
                        _label->SetRealBound(_label->GetSuitableBound().SetOrigin(10, 10));

                        // to set "enable" mode to "ON", set all states to "true"
                        _label->SetState(true, true, true, true);
                        // to set "disable" mode to "ON", set enable state to "false"
                        // _label->SetState(true, true, false, false);
                    }
                }
            }
        }
    }

    return error;
}

// result handler after text input in "enable" mode
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    // single edit label control will be passed via invoker
    // SFP16_RESULT_OK or SFP16_RESULT_ERROR will be passed via reason

    switch (reason) {

        case SFP16_RESULT_OK:
            // if text input succeeds, SFP16_RESULT_OK will be passed via reason
            // and current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

            // get inputted text
            text = _label->GetText();

            // trace inputted text on BREW Output Window
            TRACE("%S", text.GetCString());

            break;

        case SFP16_RESULT_ERROR:
            // if text input fails, SFP16_RESULT_ERROR will be passed via reason
            // and error value of SFCError type will be passed via the result argument

            ...

            break;
    }

    return;
}

9.18.3. Label Control to Display a Multiple Uneditable Text [SFZMultipleTextLabelControl]

Figure 9.53. Execution Result(Left: Unenable Mode, Right: Enable Mode)

Execution Result(Left: Unenable Mode, Right: Enable Mode)

There are 2 types of modes (i.e., "enable" and "disable") in a label control to display a multiple uneditable text(SFZMultipleTextLabelControl) depending on its enable state.

In the "enable" mode(when the state is enable), this control can be focused. In the focused state, it will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue())] if the operation key set with the SFYLabelControl::SetOperateKey function is pressed.

[Note] Note
This result event will occur in the SFZMultipleTextLabelControl::HandleOperateKey function.

If there are more rows than can be displayed in the label area, this control can be scrolled up and down by pressing the scroll keys set with the SFZMultipleTextLabelControl::SetScrollDownKey / SFZMultipleTextLabelControl::SetScrollUpKey / SFZMultipleTextLabelControl::SetPageDownKey / SFZMultipleTextLabelControl::SetPageUpKey / SFZMultipleTextLabelControl::SetSnapDownKey / SFZMultipleTextLabelControl::SetSnapUpKey functions.

This control will behave as a normal label control in the "disable" mode(when the state is disable).

Reference: State | Result Event[SFEVT_RESPONDER_RESULT]

Example 9.88. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler when the operation key is pressed in "enable" mode
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.89. Implementation

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

    // create multiple text label control
    if ((_label = SFZMultipleTextLabelControl::NewInstance(&error)) != null) {

        // set multiple text label control's parent responder to USRWindow
        error = _label->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler when the operation key is pressed in "enable" mode
            // in case of "disable" mode, it means nothing to register handler because it will not be booted up
            error = _label->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set the text to be displayed
                // * SFXWideString text can be set from the resource file
                error = _label->SetText("hello world\nabc\nxyz");
                if (error == SFERR_NO_ERROR) {

                    // set multiple text label control's real region to suitable size rectangle within region obtained by deflating USRWindow by (10, 10) [origin=(10, 10)]
                    _label->SetRealBound(_label->GetSuitableBound(GetLocalBound().Deflate(10, 10)));

                    // to set "enable" mode to "ON", set all states to "true"
                    _label->SetState(true, true, true, true);
                    // to set "disable" mode to "ON", set enable state to "false"
                    // _label->SetState(true, true, false, false);
                }
            }
        }
    }

    return error;
}

// result handler when the operation key is pressed in "enable" mode
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // multiple text label control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

    ...

    return;
}

9.18.4. Label Control to Display a Multiple Editable Text [SFZMultipleEditLabelControl]

Figure 9.54. Execution Result(Standard Input Mode)

Execution Result(Standard Input Mode)

Figure 9.55. Execution Result(Password Input Mode)

Execution Result(Password Input Mode)

There are 2 types of modes (i.e., "enable" and "disable") in a label control to display a multiple editable text(SFZMultipleEditLabelControl) depending on its enable state.

In the "enable" mode(when the state is enable), this control can be focused. In the focused state, it will transit to the text input screen if the operation key set with the SFYLabelControl::SetOperateKey function is pressed. After text input, it will receive the result event [if text input succeeds, SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue()), otherwise SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_ERROR, Error Value)].

[Note] Note
This result event will occur in the SFZMultipleEditLabelControl::HandleOperateKey function.

If there are more rows than can be displayed in the label area, this control can be scrolled up and down by pressing the scroll keys set with the SFZMultipleEditLabelControl::SetScrollDownKey / SFZMultipleEditLabelControl::SetScrollUpKey / SFZMultipleEditLabelControl::SetPageDownKey / SFZMultipleEditLabelControl::SetPageUpKey / SFZMultipleEditLabelControl::SetSnapDownKey / SFZMultipleEditLabelControl::SetSnapUpKey functions.

This control will behave as a normal label control in the "disable" mode(when the state is disable).

Reference: State | Result Event[SFEVT_RESPONDER_RESULT]

Example 9.90. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler after text input in "enable" mode
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.91. Implementation

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

    // create multiple edit label control
    if ((_label = SFZMultipleEditLabelControl::NewInstance(&error)) != null) {

        // set multiple edit label control's parent responder to USRWindow
        error = _label->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler after text input in "enable" mode
            // in case of "disable" mode, it means nothing to register handler because it will not be booted up
            error = _label->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set number input mode to "ON"
                _label->SetInputMode(AEE_TM_NUMBERS);

                // set password input mode to "ON"
                error = _label->SetPasswordMode(true);
                if (error == SFERR_NO_ERROR) {

                    // set the text to be displayed
                    // * SFXWideString text can be set from the resource file
                    error = _label->SetText("0123456789\n012\n789");
                    if (error == SFERR_NO_ERROR) {

                        // set multiple edit label control's real region to suitable size rectangle within region obtained by deflating USRWindow by (10, 10) [origin=(10, 10)]
                        _label->SetRealBound(_label->GetSuitableBound(GetLocalBound().Deflate(10, 10)));

                        // to set "enable" mode to "ON", set all states to "true"
                        _label->SetState(true, true, true, true);
                        // to set "disable" mode to "ON", set enable state to "false"
                        // _label->SetState(true, true, false, false);
                    }
                }
            }
        }
    }

    return error;
}

// result handler after text input in "enable" mode
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    // multiple edit label control will be passed via invoker
    // SFP16_RESULT_OK or SFP16_RESULT_ERROR will be passed via reason

    switch (reason) {

        case SFP16_RESULT_OK:
            // if text input succeeds, SFP16_RESULT_OK will be passed via reason
            // and current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

            // get inputted text
            text = _label->GetText();

            // trace inputted text on BREW Output Window
            TRACE("%S", text.GetCString());

            break;

        case SFP16_RESULT_ERROR:
            // if text input fails, SFP16_RESULT_ERROR will be passed via reason
            // and error value of SFCError type will be passed via the result argument

            ...

            break;
    }

    return;
}

9.18.5. Label Control to Display an Image [SFZImageLabelControl]

Figure 9.56. Execution Result(Left: Unenable Mode, Right: Enable Mode)

Execution Result(Left: Unenable Mode, Right: Enable Mode)

There are 2 types of modes (i.e., "enable" and "disable") in a label control to display an image(SFZImageLabelControl) depending on its enable state.

In the "enable" mode(when the state is enable), this control can be focused. In the focused state, it will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue())] if the operation key set with the SFYLabelControl::SetOperateKey function is pressed.

[Note] Note
This result event will occur in the SFYLabelControl::HandleOperateKey function.

This control will behave as a normal label control in the "disable" mode(when the state is disable).

Reference: State | Result Event[SFEVT_RESPONDER_RESULT]

Example 9.92. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler when the operation key is pressed in "enable" mode
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.93. Implementation

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

    // create image label control
    if ((_label = SFZImageLabelControl::NewInstance(&error)) != null) {

        // set the image label control's parent responder to USRWindow
        error = _label->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler when the operation key is pressed in "enable" mode
            // in case of "disable" mode, it means nothing to register handler because it will not be booted up
            error = _label->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set the image to be displayed
                // * SFBImage image can be set from the resource file or normal file
                error = _label->SetImage(SFXPath("resource.bar"), IMAGE_ID);
                if (error == SFERR_NO_ERROR) {

                    // set the image label control's real region to suitable size rectangle [origin=(10, 10)]
                    _label->SetRealBound(_label->GetSuitableBound().SetOrigin(10, 10));

                    // to set "enable" mode to "ON", set all states to "true"
                    _label->SetState(true, true, true, true);
                    // to set "disable" mode to "ON", set enable state to "false"
                    // _label->SetState(true, true, false, false);
                }
            }
        }
    }

    return error;
}

// result handler when the operation key is pressed in "enable" mode
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // image label control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

    ...

    return;
}

9.18.6. Box Control to Display a Single Uneditable Text [SFZSingleTextBoxControl]

Figure 9.57. Execution Result

Execution Result

Box control to display a single uneditable text(SFZSingleTextBoxControl) will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue())] if the operation key set with the SFYBoxControl::SetOperateKey function is pressed.

[Note] Note
This result event will occur in the SFZSingleTextBoxControl::HandleOperateKey function.

If there are more characters than can be displayed in the box area of a box control, this control will start to scroll automatically when it is in the focused state.

Reference: Result Event[SFEVT_RESPONDER_RESULT]

Example 9.94. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler when the operation key is pressed
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.95. Implementation

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

    // create single text box control
    if ((_box = SFZSingleTextBoxControl::NewInstance(&error)) != null) {

        // set single text box control's parent responder to USRWindow
        error = _box->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler when the operation key is pressed
            error = _box->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set the text to be displayed
                // * SFXWideString text can be set from the resource file
                error = _box->SetText("hello world");
                if (error == SFERR_NO_ERROR) {

                    // set single text box control's real region to suitable size rectangle [origin=(10, 10)]
                    _box->SetRealBound(_box->GetSuitableBound().SetOrigin(10, 10));

                    // set single text box control's state to "visible" + "active" + "enable" + "focus" together
                    _box->SetState(true, true, true, true);
                }
            }
        }
    }

    return error;
}

// result handler when the operation key is pressed
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // single text box control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

    ...

    return;
}

9.18.7. Box Control to Display a Single Editable Text [SFZSingleEditBoxControl]

Figure 9.58. Execution Result(Standard Input Mode)

Execution Result(Standard Input Mode)

Figure 9.59. Execution Result(Password Input Mode)

Execution Result(Password Input Mode)

Box control to display a single editable text(SFZSingleEditBoxControl) can be focused. In the focused state, it will transit to the text input screen if the operation key set with the SFYBoxControl::SetOperateKey function is pressed. After text input, it will receive the result event [if text input succeeds, SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue()), otherwise SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_ERROR, Error Value)].

[Note] Note
This result event will occur in the SFZSingleEditBoxControl::HandleOperateKey function.

If there are more characters than can be displayed in the box area of a box control, this control will start to scroll automatically when it is in the focused state.

Reference: Result Event[SFEVT_RESPONDER_RESULT]

Example 9.96. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler after text input
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.97. Implementation

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

    // create single edit box control
    if ((_box = SFZSingleEditBoxControl::NewInstance(&error)) != null) {

        // set single edit box control's parent responder to USRWindow
        error = _box->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler after text input
            error = _box->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set number input mode to "ON"
                _box->SetInputMode(AEE_TM_NUMBERS);

                // set password input mode to "ON"
                error = _box->SetPasswordMode(true);
                if (error == SFERR_NO_ERROR) {

                    // set the text to be displayed
                    // * SFXWideString text can be set from the resource file
                    error = _box->SetText("0123456789");
                    if (error == SFERR_NO_ERROR) {

                        // set single edit box control's real region to suitable size rectangle [origin=(10, 10)]
                        _box->SetRealBound(_box->GetSuitableBound().SetOrigin(10, 10));

                        // set single edit box control's state to "visible" + "active" + "enable" + "focus" together
                        _box->SetState(true, true, true, true);
                    }
                }
            }
        }
    }

    return error;
}

// result handler after text input
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    // single edit box control will be passed via invoker
    // SFP16_RESULT_OK or SFP16_RESULT_ERROR will be passed via reason

    switch (reason) {

        case SFP16_RESULT_OK:
            // if text input succeeds, SFP16_RESULT_OK will be passed via reason
            // and current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

            // get inputted text
            text = _box->GetText();

            // trace inputted text on BREW Output Window
            TRACE("%S", text.GetCString());

            break;

        case SFP16_RESULT_ERROR:
            // if text input fails, SFP16_RESULT_ERROR will be passed via reason
            // and error value of SFCError type will be passed via the result argument

            ...

            break;
    }

    return;
}

9.18.8. Box Control to Display a Multiple Uneditable Text [SFZMultipleTextBoxControl]

Figure 9.60. Execution Result

Execution Result

Box control to display a multiple uneditable text(SFZMultipleTextBoxControl) will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue())] if the operation key set with the SFYBoxControl::SetOperateKey function is pressed.

[Note] Note
This result event will occur in the SFZMultipleTextBoxControl::HandleOperateKey function.

If there are more rows than can be displayed in the box area, this control can be scrolled up and down by pressing the scroll keys set with the SFZMultipleTextBoxControl::SetScrollDownKey / SFZMultipleTextBoxControl::SetScrollUpKey / SFZMultipleTextBoxControl::SetPageDownKey / SFZMultipleTextBoxControl::SetPageUpKey / SFZMultipleTextBoxControl::SetSnapDownKey / SFZMultipleTextBoxControl::SetSnapUpKey functions.

Reference: Result Event[SFEVT_RESPONDER_RESULT]

Example 9.98. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler when the operation key is pressed
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.99. Implementation

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

    // create multiple text box control
    if ((_box = SFZMultipleTextBoxControl::NewInstance(&error)) != null) {

        // set multiple text box control's parent responder to USRWindow
        error = _box->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler when the operation key is pressed
            error = _box->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set the text to be displayed
                // * SFXWideString text can be set from the resource file
                error = _box->SetText("hello world\nabc\nxyz");
                if (error == SFERR_NO_ERROR) {

                    // set multiple text box control's real region to suitable size rectangle within region obtained by deflating USRWindow by (10, 10) [origin=(10, 10)]
                    _box->SetRealBound(_box->GetSuitableBound(GetLocalBound().Deflate(10, 10)));

                    // set multiple edit box control's state to "visible" + "active" + "enable" + "focus" together
                    _box->SetState(true, true, true, true);
                }
            }
        }
    }

    return error;
}

// result handler when the operation key is pressed
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // multiple text box control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

    ...

    return;
}

9.18.9. Box Control to Display a Multiple Editable Text [SFZMultipleEditBoxControl]

Figure 9.61. Execution Result(Standard Input Mode)

Execution Result(Standard Input Mode)

Figure 9.62. Execution Result(Password Input Mode)

Execution Result(Password Input Mode)

Box control to display a multiple editable text(SFZMultipleEditBoxControl) can transit to the text input screen if the operation key set with the SFYBoxControl::SetOperateKey function is pressed. After text input, it will receive the result event [if text input succeeds, SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue()), otherwise SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_ERROR, Error Value)].

[Note] Note
This result event will occur in the SFZMultipleEditBoxControl::HandleOperateKey function.

If there are more rows than can be displayed in the box area, this control can be scrolled up and down by pressing the scroll keys set with the SFZMultipleEditBoxControl::SetScrollDownKey / SFZMultipleEditBoxControl::SetScrollUpKey / SFZMultipleEditBoxControl::SetPageDownKey / SFZMultipleEditBoxControl::SetPageUpKey / SFZMultipleEditBoxControl::SetSnapDownKey / SFZMultipleEditBoxControl::SetSnapUpKey functions.

Reference: Result Event[SFEVT_RESPONDER_RESULT]

Example 9.100. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler after text input
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.101. Implementation

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

    // create multiple edit box control
    if ((_box = SFZMultipleEditBoxControl::NewInstance(&error)) != null) {

        // set multiple edit box control's parent responder to USRWindow
        error = _box->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler after text input
            error = _box->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set number input mode to "ON"
                _box->SetInputMode(AEE_TM_NUMBERS);

                // set password input mode to "ON"
                error = _box->SetPasswordMode(true);
                if (error == SFERR_NO_ERROR) {

                    // set the text to be displayed
                    // * SFXWideString text can be set from the resource file
                    error = _box->SetText("0123456789\n012\n789");
                    if (error == SFERR_NO_ERROR) {

                        // set multiple edit box control's real region to suitable size rectangle within region obtained by deflating USRWindow by (10, 10) [origin=(10, 10)]
                        _box->SetRealBound(_box->GetSuitableBound(GetLocalBound().Deflate(10, 10)));

                        // set multiple edit box control's state to "visible" + "active" + "enable" + "focus" together
                        _box->SetState(true, true, true, true);
                    }
                }
            }
        }
    }

    return error;
}

// handler for event after text input
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    // multiple edit box control will be passed via invoker
    // SFP16_RESULT_OK or SFP16_RESULT_ERROR will be passed via reason

    switch (reason) {

        case SFP16_RESULT_OK:
            // if text input succeeds, SFP16_RESULT_OK will be passed via reason
            // and current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

            // get inputted text
            text = _box->GetText();

            // trace inputted text on BREW Output Window
            TRACE("%S", text.GetCString());

            break;

        case SFP16_RESULT_ERROR:
            // if text input fails, SFP16_RESULT_ERROR will be passed via reason
            // and error value of SFCError type will be passed via the result argument

            ...

            break;
    }

    return;
}

9.18.10. Box Control to Display an Image [SFZImageBoxControl]

Figure 9.63. Execution Result

Execution Result

Box control to display an image(SFZImageBoxControl) will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue())] if the operation key set with the SFYBoxControl::SetOperateKey function is pressed.

[Note] Note
This result event will occur in the SFYBoxControl::HandleOperateKey function.

Reference: Result Event[SFEVT_RESPONDER_RESULT]

Example 9.102. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler when the operation key is pressed
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.103. Implementation

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

    // create image box control
    if ((_box = SFZImageBoxControl::NewInstance(&error)) != null) {

        // set the image box control's parent responder to USRWindow
        error = _box->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler when the operation key is pressed
            error = _box->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set the image to be displayed
                // * SFBImage image can be set from the resource file or normal file
                error = _box->SetImage(SFXPath("resource.bar"), IMAGE_ID);
                if (error == SFERR_NO_ERROR) {

                    // set the image box control's real region to suitable size rectangle [origin=(10, 10)]
                    _box->SetRealBound(_box->GetSuitableBound().SetOrigin(10, 10));

                    // set the image box control's state to "visible" + "active" + "enable" + "focus" together
                    _box->SetState(true, true, true, true);
                }
            }
        }
    }

    return error;
}

// result handler when the operation key is pressed
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // image box control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

    ...

    return;
}

9.18.11. Text Button Control to Display a Text [SFZTextButtonControl]

Figure 9.64. Execution Result

Execution Result

Text button control to display a text(SFZTextButtonControl) will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue())] if the operation key set with the SFYButtonControl::SetOperateKey function is released after pressed.

[Note] Note
This result event will occur in the SFYButtonControl::HandleOperateKeyRelease function.

If there are more characters than can be displayed in the text region of a button control, this control will start to scroll automatically when it is in the focused state.

Reference: Result Event[SFEVT_RESPONDER_RESULT]

Example 9.104. Declaration

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

    ...
private:
    SFCError Make(Void);

    // handler to handles result event when text button control is operated
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.105. Implementation

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

    // create text button control
    if ((_button = SFZTextButtonControl::NewInstance(&error)) != null) {

        // set the text button control's parent responder to USRWindow
        error = _button->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler when text button control is operated
            error = _button->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set the text to be displayed
                // * SFXWideString text can be set from the resource file
                error = _button->SetText("hello world");
                if (error == SFERR_NO_ERROR) {

                    // set the text button control's real region to suitable size rectangle [origin=(10, 10)]
                    _button->SetRealBound(_button->GetSuitableBound().SetOrigin(10, 10));

                    // set the text button control's state to "visible" + "active" + "enable" + "focus" together
                    _button->SetState(true, true, true, true);
                }
            }
        }
    }

    return error;
}

// handler to handles result event when text button control is operated
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // text button control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

    ...

    return;
}

9.18.12. Image Button Control to Display an Image [SFZImageButtonControl]

Figure 9.65. Execution Result

Execution Result

Image button control to display an image(SFZImageButtonControl) will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue())] if the operation key set with the SFYButtonControl::SetOperateKey function is released after pressed.

[Note] Note
This result event will occur in the SFYButtonControl::HandleOperateKeyRelease function.

Reference: Result Event[SFEVT_RESPONDER_RESULT]

Example 9.106. Declaration

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

    ...
private:
    SFCError Make(Void);

    // handler to handles result event when image button control is operated
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.107. Implementation

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

    // create image button control
    if ((_button = SFZImageButtonControl::NewInstance(&error)) != null) {

        // set the image button control's parent responder to USRWindow
        error = _button->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler when image button control is operated
            error = _button->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set the image to be displayed
                // * SFBImage image can be set from the resource file or normal file
                error = _button->SetImage(SFXPath("resource.bar"), IMAGE_ID);
                if (error == SFERR_NO_ERROR) {

                    // set the image button control's real region to suitable size rectangle [origin=(10, 10)]
                    _button->SetRealBound(_button->GetSuitableBound().SetOrigin(10, 10));

                    // set the image button control's state to "visible" + "active" + "enable" + "focus" together
                    _button->SetState(true, true, true, true);
                }
            }
        }
    }

    return error;
}

// handler to handles result event when image button control is operated
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // image button control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

    ...

    return;
}

9.18.13. Control to Display a Scroll Bar [SFZScrollBarControl]

Figure 9.66. Execution Result

Execution Result

A responder can be scrolled when its virtual region is larger than its real region.

Scroll bar control(SFZScrollBarControl) is a control bound with this scrollable responder to indicate the position of the scrollable information in its real region.

[Note] Note

In a scroll bar control, when the scrollable state of its bound responder is changed into the unscrollable state or vice versa, the scroll bar event[SFEVT_RESPONDER_SCROLLBAR] [SFXEvent(SFEVT_RESPONDER_SCROLLBAR, SFP16_SCROLLBAR_ENABLE, 0)] will occur.

[Note] Note

Information on whether or not the sate is scrollable currently can be obtained with the SFYScrollBarControl::IsScrollable function.

Reference: Scroll Bar Event[SFEVT_RESPONDER_SCROLLBAR]

Example 9.108. Declaration

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

public:
    SFCError Make(Void);

    // ...
private:

    // function to set position and size of scroll bar thumb by reading container's region information
    Void Listen(SFYResponderPtr container);

    // container's handler for real and virtual region events
    XANDLER_DECLARE_VOIDBOUND(OnContainerBound)
};

Example 9.109. Implementation

#define SCROLLBAR_WIDTH 5

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

    // create container
    if ((_container = SFZContainer::NewInstance(&error)) != null) {

        // set container's parent responder to USRWindow
        error = _container->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register handler for real and virtual region events into container
            error = _container->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_BOUND, SFEVT_RESPONDER_BOUND, SFP16_BOUND_REAL, SFP16_BOUND_VIRTUAL),
                XANDLER_INTERNAL(OnContainerBound)
            );
            if (error == SFERR_NO_ERROR) {

                // set container's background color
                _container->SetBackgroundColor(SFXRGBColor(0xFF, 0xCC, 0xCC, 0x00));

                // set container's real region window's to local region excluding scroll bar's region
                _container->SetRealBound(GetLocalBound().SubWidth(SCROLLBAR_WIDTH));

                // set container's virtual region to region obtained by expanding container's real region up and down each by 100 pixels
                _container->SetVirtualBound(SFXRectangle(_container->GetRealBound()).Inflate(0, 100));

                // set container's state to "visible" + "active" + "enable" + "focus" together
                _container->SetState(true, true, true, true);

                // create scroll bar control
                if ((_bar = SFZScrollBarControl::NewInstance(&error)) != null) {

                    // set scroll bar control's parent responder to USRWindow
                    error = _bar->SetParent(GetThis());
                    if (error == SFERR_NO_ERROR) {

                        // place scroll bar control directly on right side of container
                        _bar->SetRealBound(GetLocalBound().SetX(_container->GetRealBound().GetRight()).SetWidth(SCROLLBAR_WIDTH));

                        // set scroll bar control's state to "visible" + "active" + "disable" + "unfocus" together
                        _bar->SetState(true, true, false, false);

                        // set position and size of scroll bar thumb by reading container's region information
                        Listen(_container.Get());
                    }
                }
            }
        }
    }

    return error;
}

// function to set position and size of scroll bar thumb by reading container's region information
Void USRWindow::Listen(SFYResponderPtr container)
{
    SFXRectangle rx;
    SFXRectangle vx;
    SInt16 max;
    SInt16 cur;
    SInt16 page;

    if (_bar != null & container != null) {

        // get container's real region
        rx = container->GetRealBound();

        // get container's virtual region
        vx = container->GetVirtualBound();

        if (_bar->GetOrientation() == SFYScrollBarControl::VERTICAL) {
            // if scroll orientation is vertical

            // set max to height of virtual region
            max = vx.GetHeight();

            // set cur to Y value of real region origin in local region coordinate
            cur = -vx.GetTop();

            // set page to height of real region
            page = rx.GetHeight();
        }
        else {
            // if scroll orientation is horizontal

            // set max to width of virtual region
            max = vx.GetWidth();

            // set cur to X value of real region origin in local region coordinate
            cur = -vx.GetLeft();

            // set page to height of real region
            page = rx.GetWidth();
        }


        // set minimum value (this value is always 0)
        _bar->SetMinimumValue(0);

        // set maximum value (this value is width or height of virtual region)
        _bar->SetMaximumValue(max);

        // set current value (this value is X or Y value of real region origin in local region coordinate)
        _bar->SetCurrentValue(cur);

        // set page size value (this value is width or height of real region)
        _bar->SetPageValue(page);
    }
}

// handler for real and virtual region events
XANDLER_IMPLEMENT_VOIDBOUND(USRWindow, OnContainerBound, invoker, reason, bound)
{
    unused(reason);
    unused(bound);

    // container control will be passed via invoker

    // update position and size of scroll bar thumb when container's region is changed
    Listen(invoker);
}

9.18.14. Control to Display a Scroll Bar for Container [SFZContainerScrollBarControl]

Figure 9.67. Execution Result

Execution Result

SFZContainerScrollBarControl is a scroll bar control for a container.

In SFZContainerScrollBarControl, there is no need to register a handler for real and virtual region events into a container nor set the position and the size of the scroll bar thumb by reading container's region information with the SFZContainerScrollBarControl::Bind function instead.

Example 9.110. Declaration

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

public:
    SFCError Make(Void);

    // ...
};

Example 9.111. Implementation

#define SCROLLBAR_WIDTH 5

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

    // create container
    if ((_container = SFZContainer::NewInstance(&error)) != null) {

        // set container's parent responder to USRWindow
        error = _container->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // set container's background color
            _container->SetBackgroundColor(SFXRGBColor(0xFF, 0xCC, 0xCC, 0x00));

            // set container's real region to window's local region excluding scroll bar's region
            _container->SetRealBound(GetLocalBound().SubWidth(SCROLLBAR_WIDTH));

            // set container's virtual region to region obtained by expanding container's real region up and down each by 100 pixels
            _container->SetVirtualBound(SFXRectangle(_container->GetRealBound()).Inflate(0, 100));

            // set container's state to "visible" + "active" + "enable" + "focus" together
            _container->SetState(true, true, true, true);

            // create scroll bar control
            if ((_bar = SFZContainerScrollBarControl::NewInstance(&error)) != null) {
                error = _bar->SetParent(GetThis());
                if (error == SFERR_NO_ERROR) {

                    // place scroll bar control directly on right side of container
                    _bar->SetRealBound(GetLocalBound().SetX(_container->GetRealBound().GetRight()).SetWidth(SCROLLBAR_WIDTH));

                    // set scroll bar control's state to "visible" + "active" + "disable" + "unfocus" together
                    _bar->SetState(true, true, false, false);

                    // bind container with scroll bar control
                    _bar->Bind(_container);
                }
            }
        }
    }

    return error;
}

9.18.15. List Box Control [SFZListBoxControl]

Figure 9.68. Execution Result

Execution Result

List box control(SFZListBoxControl) is a control to have a user select one item among list items.

In SFZListBoxControl, the focused item, currently selected item, is displayed highlightly.

[Note] Note
If an item is in the invalid state, it will not be focused nor selected.

To insert an item, use the SFZListBoxControl::Insert / SFZListBoxControl::InsertFirst / SFZListBoxControl::InsertLast function. To remove an item, use the SFZListBoxControl::Remove / SFZListBoxControl::RemoveFirst / SFZListBoxControl::RemoveLast function. If the SFZListBoxControl::Clear function is called, all items are removed.

The selected item can be moved using the UP key set with the SFZListBoxControl::SetUpKey function or the DOWN key set with the SFZListBoxControl::SetDownKey function.

If the selected item is moved, the value event of SFXEvent(SFEVT_RESPONDER_VALUE, SFP16_VALUE_CURRENT, index of selected item) will be sent by the internal handler of this list box control.

[Note] Note
This value event will occur in the SFYControl::SetCurrentValue function called internally in SFZListBoxControl.

In the selected item, the text is drawn in the color set with the SFZListBoxControl::SetSelForeColor function, and the background is filled in the color set with the SFZListBoxControl::SetSelBackColor function.

In the unselected item, the text is drawn in the color set with the SFZListBoxControl::SetItemForeColor function, and the background is filled in the color set with the SFZListBoxControl::SetItemBackColor function.

The grid line can be drawn with the SFZListBoxControl::SetGridLineEnable and SFZListBoxControl::SetGridLineColor functions. The margin between two items can be set with the SFZListBoxControl::SetListMargin function.

In the default implementation, the list box control[SFZListBoxControl] will receive the following result events[SFEVT_RESPONDER_RESULT].

The developer can register handlers for these events.

The operation key is set with the SFYBoxControl::SetOperateKey function. By default, the operation key is set to the SELECT key.

The access key is set with the SFZListBoxControl::SetItemAccessKey function.

The ESCAPE key is set with the SFZListBoxControl::SetEscapeKey function. By default, the ESCAPE key is set to the CLEAR key.

[Caution] Caution
The result event will not occur when the enable flag of selected item is set to "false" with the SFZListBoxControl::SetItemEnable function.

Reference: Result Event[SFEVT_RESPONDER_RESULT] | SFZListBoxControl::HandleOperateKey | SFZListBoxControl::HandleAccessKey | SFZListBoxControl::HandleEscapeKey

Example 9.112. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler when list box control is operated
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.113. Implementation

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

    // create list box control
    if ((_listbox = SFZListBoxControl::NewInstance(&error)) != null) {

        // set list box control's parent responder to USRWindow
        error = _listbox->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler
            error = _listbox->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                for (SInt32 i = 0; i < 20; ++i) {

                    // append item
                    error = _listbox->InsertLast(SFXWideString::Format("Item index is %d", i));

                    if (error != SFERR_NO_ERROR) break;
                }
                if (error == SFERR_NO_ERROR) {

                    // set list box control's real region to suitable size rectangle [origin=(20, 20)]
                    _listbox->SetRealBound(_listbox->GetSuitableBound(GetLocalBound().Deflate(20, 20)).SetOrigin(20, 20));

                    // set list box control's state to "visible" + "active" + "enable" + "focus" together
                    _listbox->SetState(true, true, true, true);
                }
            }
        }
    }

    return error;
}

// result handler when list box control is operated
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    // list box control will be passed via invoker
    // SFP16_RESULT_OK or SFP16_RESULT_ESCAPE will be passed via reason

    switch (reason) {

        case SFP16_RESULT_OK:
            // when the operation key is pressed, SFP16_RESULT_OK will be passed via reason
            // and current value will be passed via the result argument [ current value = index of selected item or return value of GetCurrentValue() ]

            // get the text of the selected item
            text = _listbox->GetItemText(result);

            // trace text of selected item on BREW Output Window
            TRACE("%S", text.GetCString());

            break;

        case SFP16_RESULT_ESCAPE:
            // when the ESCAPE key is pressed, SFP16_RESULT_ESCAPE will be passed via reason
            // and "0" will be passed via the result argument

            ...

            break;
    }

    return;
}

9.18.16. Combo Box Control [SFZComboBoxControl]

Figure 9.69. Execution Result

Execution Result

Combo box control(SFZComboBoxControl) is a button control which internally contains a flex list box control(SFZFlexListBoxControl) for list items.

To insert an item, use the SFZComboBoxControl::Insert / SFZComboBoxControl::InsertFirst / SFZComboBoxControl::InsertLast function. To remove an item, use the SFZComboBoxControl::Remove / SFZComboBoxControl::RemoveFirst / SFZComboBoxControl::RemoveLast function. If the SFZComboBoxControl::Clear function is called, all items are removed.

In the region of this combo box control, the currently selected item among this flex list box control is displayed.

If there are more characters than can be displayed in the text region of a combo box control, this control will start to scroll automatically when it is in the focused state.

The flex list box control(SFZFlexListBoxControl) internally contained by the combo box control(SFZComboBoxControl) will be opened if the pull-down button where the reverse triangle is drawn is released after pressed using the operation key of the combo box control set with the SFYButtonControl::SetOperateKey.

In SFZFlexListBoxControl, the focused item, currently selected item, is displayed highlightly.

[Note] Note
If an item is in the invalid state, it will not be focused nor selected.

List items can be scrolled using the scroll keys set with the SFZFlexListBoxControl::SetScrollUpKey / SFZFlexListBoxControl::SetScrollDownKey / SFZFlexListBoxControl::SetPageUpKey / SFZFlexListBoxControl::SetPageDownKey / SFZFlexListBoxControl::SetSnapUpKey / SFZFlexListBoxControl::SetSnapDownKey functions.

  1. When the flex list box control is opened, the flex list box control will be closed by pressing the operation key or the access key. Then, the selected item will be displayed in the combo box control. [*Prerequisite: the selected item needs to be enabled with the SFZFlexListBoxControl::SetItemEnable function]

    In this case, the combo box control will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, index of the selected item)].

    [Tip] Tip
    The operation key of the flex list box control is set with the SFYBoxControl::SetOperateKey function. By default, the operation key is set to the SELECT key.
    [Tip] Tip
    The access key is set with the SFZFlexListBoxControl::SetItemAccessKey function.
    [Caution] Caution
    When the selected item is disabled with the SFZFlexListBoxControl::SetItemEnable function, nothing will happen if the operation key or the access key is pressed.
  2. When the flex list box control is opened, the flex list box control will be closed by pressing the ESCAPE key. The content of the combo box control will be the same as before the flex list box control is opened.

    [Tip] Tip
    The ESCAPE key is set with the SFZFlexListBoxControl::SetEscapeKey function. By default, the ESCAPE key is set to the CLEAR key.
    [Caution] Caution
    In this case, no result event will occur in this combo box control.

Reference: Result Event[SFEVT_RESPONDER_RESULT]

[Caution] CAUTION

The region of a flex list box control internally contained by a combo box control is automatically set based on inserted items and the local region of its parent responder where the combo box control is placed.

To draw the flex list box control, the real region(local region) of its parent responder needs to be set with the SFYResponder::SetRealBound function.

This real region is the same with its local region unless its virtual region is set with the SFYResponder::SetVirtualBound function.

* Both the local region and the virtual region represent the same rectangular region.

Example 9.114. Declaration

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

    // ...
private:
    SFCError Make(Void);

    // result handler
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.115. Implementation

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

    // create combo box control
    if ((_combobox = SFZComboBoxControl::NewInstance(&error)) != null) {

        // set combo box control's parent responder to USRWindow
        error = _combobox->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler into the combo box control
            error = _combobox->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                for (SInt32 i = 0; i < 10; ++i) {

                    // append item on flex list box control internally contained by combo box control
                    error = _combobox->InsertLast(SFXWideString::Format("Item index is %d.", i));

                    if (error != SFERR_NO_ERROR) break;
                }
                if (error == SFERR_NO_ERROR) {

                    // set combo box control's real region to suitable size rectangle [origin=(20, 20)]
                    _combobox->SetRealBound(_combobox->GetSuitableBound(GetLocalBound().Deflate(20, 20)).SetOrigin(20, 20));

                    // set combo box control's state to "visible" + "active" + "enable" + "focus" together
                    _combobox->SetState(true, true, true, true);
                }
            }
        }
    }

    return error;
}

// result handler
// * this handler will not be booted up when value is changed by SetCurrentValue function
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    SFXWideString text;

    // combo box control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = [ current value = index of selected item or return value of GetCurrentValue() ]

    // get the text of the selected item
    text = _combobox->GetItemText(result);

    // trace text of selected item on BREW Output Window
    TRACE("%S", text.GetCString());

    return;
}

9.18.17. Check Box Control [SFZCheckboxControl]

Figure 9.70. Execution Result

Execution Result

Check box control(SFZCheckboxControl) will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue())] if the operation key set with the SFYButtonControl::SetOperateKey function is released after pressed.

[Note] Note
This result event will occur in the SFYCheckboxControl::HandleOperateKeyRelease function.

If there are more characters than can be displayed in the text region of a check box control, this control will start to scroll automatically when it is in the focused state.

Reference: Result Event[SFEVT_RESPONDER_RESULT]

Example 9.116. Declaration

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

    ...
private:
    SFCError Make(Void);

    // result handler when check box control is operated
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.117. Implementation

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

    // create check box control
    if ((_checkbox = SFZCheckboxControl::NewInstance(&error)) != null) {

        // set check box control's parent responder to USRWindow
        error = _checkbox->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler when check box control is operated
            error = _checkbox->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set the text to be displayed
                // * SFXWideString text can be set from the resource file
                error = _checkbox->SetText("hello world");
                if (error == SFERR_NO_ERROR) {

                    // set check box control's current value to "true" (i.e., checked state)
                    _checkbox->SetCurrentValue(true);

                    // set check box control's real region to suitable size rectangle [origin=(10, 10)]
                    _checkbox->SetRealBound(_checkbox->GetSuitableBound().SetOrigin(10, 10));

                    // set check box control's state to "visible" + "active" + "enable" + "focus" together
                    _checkbox->SetState(true, true, true, true);
                }
            }
        }
    }

    return error;
}

// result handler when check box control is operated
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // check box control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

    ...

    return;
}

9.18.18. Radio Button Control [SFZRadiobuttonControl]

Figure 9.71. Execution Result

Execution Result

Radio button control(SFZRadiobuttonControl) will receive the result event [SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, SFYControl::GetCurrentValue())] if the operation key set with the SFYButtonControl::SetOperateKey function is released after pressed.

[Note] Note
This result event will occur in the SFYRadiobuttonControl::HandleOperateKeyRelease function.

If there are more characters than can be displayed in the text region of a radio button control, this control will start to scroll automatically when it is in the focused state.

By grouping more than one radio button control, exclusive choice is automatically implemented.

Reference: Result Event[SFEVT_RESPONDER_RESULT]

Example 9.118. Declaration

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

    ...
private:
    SFCError Make(Void);

    // handler to handles result event when radio button control is operated
    XANDLER_DECLARE_VOIDRESULT(OnResult)
};

Example 9.119. Implementation

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

    // create radio button control
    if ((_radiobutton = SFZRadiobuttonControl::NewInstance(&error)) != null) {

        // set radio button control's parent responder to USRWindow
        error = _radiobutton->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // register the result handler when radio button control is operated
            error = _radiobutton->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnResult)
            );
            if (error == SFERR_NO_ERROR) {

                // set the text to be displayed
                // * SFXWideString text can be set from the resource file
                error = _radiobutton->SetText("hello world");
                if (error == SFERR_NO_ERROR) {

                    // set radio button control's current value to "true" (i.e., checked state)
                    _radiobutton->SetCurrentValue(true);

                    // set radio button control's real region to suitable size rectangle [origin=(10, 10)]
                    _radiobutton->SetRealBound(_radiobutton->GetSuitableBound().SetOrigin(10, 10));

                    // set radio button control's state to "visible" + "active" + "enable" + "focus" together
                    _radiobutton->SetState(true, true, true, true);
                }
            }
        }
    }

    return error;
}

// handler to handles result event when radio button control is operated
XANDLER_IMPLEMENT_VOIDRESULT(USRWindow, OnResult, invoker, reason, result)
{
    // radio button control will be passed via invoker
    // SFP16_RESULT_OK will be passed via reason
    // the current value will be passed via the result argument [ current value = return value of GetCurrentValue() ]

    ...

    return;
}

9.18.19. Tab Control and Tab Page [SFZTabControl and SFZTabPage]

Figure 9.72. Execution Result

Execution Result

SFZTabControl is a control to provide the tabbed user interface.

Each tab of the tab control is managed by the tab page(SFZTabPage).

Though the real region of the tab control needs to be set with the SFYResponder::SetRealBound function, that of the tab page is automatically set based on the tab control region.

Concretely, it is the region obtained by subtracting the hint region and the tab region from the tab control region.

[Note] Design of the tab

The functions to draw a text or an image on the tab region as a title label are available.

[Note] Initial states of the tab page

Immediately after creating the tab page(SFZTabPage instance), its state is automatically set to "visible" + "active" + "enable" + "unfocus" together as an initial value.

In almost all cases, since this setting is enough, you don't have to set the tab page's state.

[Caution] Moving the tab page foremost

To move the tab page foremost among tab pages in the tab control, call the SFYTabControl::FocusPage function by specifying its index as an argument.

Since there is a possibility that the selected tab may not match the tab page placed foremost currently, it is prohibited to call the tab page's functions such as SFYResponder::ToFront or SFYResponder::SetStateFocus which may chage the order relation of the tab pages.

[Note] Focus state of the tab page

The focus state of the tab page(SFZTabPage instance) will be automatically set to "true" if the tab page is placed foremost among tab pages in the tab control, otherwise it will be set to "false".

[Note] Real region of the tab page

Since the real region of the tab page is set automatically, you don't have to set this. Even if you try to change its real region with the SFYResponder::SetRealBound function, it will be restored to the origin.

[Caution] Deleting the tab page from the tab control

The method to delete the tab page from the tab control dynamically is as follows:

The code to delete the tab page from the tab control is as follows:

// CASE 1. Preserve the tab page (set tab page's parent to the empty instance):
page->SetParent(SFYResponder::EmptyInstance());

// CASE 2. Use tab page for another tab control (set tab page's parent to another tab control):
SFYTabControlSmp othertab;
page->SetParent(othertab);

// CASE 3. Destroy tab page: 
page->Terminate();

Example 9.120. Declaration

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

    ...
private:
    SFCError Make(Void);
};

Example 9.121. Implementation

SFCError USRWindow::Make(Void)
{
    SFBShellSmp shell;
    SFBImageSmp image;
    SFXWideString text;
    SFZTabPageSmp page[4];
    SFZTextButtonControlSmp button[4];
    SFXRectangle rectangle;
    SInt16 i;
    SFCError error(SFERR_NO_ERROR);

    // create tab control
    if ((_tab = SFZTabControl::NewInstance(&error)) != null) {

        // set tab control's parent responder to USRWindow
        error = _tab->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

            // set tab control's real region to USRWindow's local region
            _tab->SetRealBound(GetLocalBound());

            // set tab control's background color
            _tab->SetBackgroundColor(SFXRGBColor(0xDD, 0xFF, 0xDD, 0x00));

            // set number of pages to be displayed in tab control region to 3
            _tab->SetFieldValue(3);

            // set tab control's state to "visible" + "active" + "enable" + "focus" together
            _tab->SetState(true, true, true, true);

            // get SFBShell instance
            shell = SFBShell::GetInstance();

            if (shell != null) {

                // make 4 tab pages and append them
                for (i = 0; i < 4; ++ i) {

                    // create tab page
                    page[i] = SFZTabPage::NewInstance(&error);
                    if (page[i] != null) {

                        // set tab page's parent responder to tab control
                        // * since tab page's real region will be automatically set, you don't have to set it
                        error = page[i]->SetParent(_tab);

                        if (error == SFERR_NO_ERROR) {

                            // set tab page's title text
                            text = SFXWideString::Format("%c", 'A' + i);
                            page[i]->SetTitle(text);

                            // set tab page's hint text
                            text = SFXWideString::Format("Page %d", i);
                            error = page[i]->SetHint(text);
                            if (error == SFERR_NO_ERROR) {

                                // read image to be displayed from the resource file
                                image = shell->LoadResImage(TAB_RES_FILE, IDI_OBJECT_5001 + i);
                                if (image != null) {

                                    // set tab page's title image (this image can be set from the resource file or normal file)
                                    page[i]->SetImage(image);

                                    // set tab page's state to "visible" + "active" + "enable" + "unfocus" together
                                    // * this statement can be omitted since it is initial state of SFZTabPage instance
                                    page[i]->SetState(true, true, true, false);

                                    // place button in center of tab page

                                    // create text button control
                                    if ((button[i] = SFZTextButtonControl::NewInstance(&error)) != null) {

                                        // set the text button control's parent responder to tab page
                                        error = button[i]->SetParent(page[i]);

                                        if (error == SFERR_NO_ERROR) {

                                            // set the text button control's label text
                                            error = button[i]->SetText(SFXWideString::Format("Button %c", 'A' + i));

                                            if (error == SFERR_NO_ERROR) {

                                                // calculate text button control's suitable region size
                                                rectangle = button[i]->GetSuitableBound(page[i]->GetLocalBound());

                                                // place text button control's suitable region in center of tab page
                                                rectangle.SnapCenterMiddle(page[i]->GetLocalBound().GetCenterMiddle());

                                                // set the text button control's real region
                                                button[i]->SetRealBound(rectangle);

                                                // set the text button control's state to "visible" + "active" + "enable" + "focus" together
                                                button[i]->SetState(true, true, true, true);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (error != SFERR_NO_ERROR) break;
                }
                if (error == SFERR_NO_ERROR) {

                    // move and display 1st tab page foremost
                    // by specifying index of tab page in argument of FocusPage()
                    _tab->FocusPage(0);

                    // following two methods to move tab page foremost are prohibited
                    // since there is possibility that selected tab may not match tab page placed foremost currently

                    // Method 1. move 1st tab page foremost by moving the focus
                    // NG: page[0]->SetStateFocus(true);

                    // Method 2. move 1st tab page foremost by calling ToFront()
                    // NG: page[0]->ToFront();
                }
            }
        }
    }

    return error;
}

9.18.20. SoftKey Control [SFZSoftKeyControl]

SoftKey control(SFZSoftKeyControl) is a control to handle the key events from SoftKey, and there are 2 types of the SoftKey controls depending on the number of labels which constitute its SoftKey menu as follows:

  1. Standard style: Labels for 3 soft keys constitute its SoftKey menu.
  2. Extention style: Labels for 5 soft keys and 4 cursor keys constitute its SoftKey menu.

[Note] Note
Default is the standard style.

Figure 9.73. Standard style


Standard style

Standard style: Labels for 3 soft keys constitute its SoftKey menu.

Figure 9.74. Extention style


Extention style

Extention style: Labels for 5 soft keys and 4 cursor keys constitute its SoftKey menu.

The below is the layout of SoftKey control.

Standard style:

Extention style:

[Note] Background color of the SoftKey control

The default background color of the SoftKey control(SFZSoftKeyControl) is set to SFXRGBColor(0xCC, 0xCC, 0xCC, 0x00) [gray color].

This background color can be changed with the SFYWidget::SetBackgroundColor function.

Functions of the SoftKey control(SFZSoftKeyControl) are as follows:

  1. Bind or unbind a responder with or from the SoftKey control( and a SoftKey menu).
  2. When the foremost focused responder, called "active responder", bound with the SoftKey control is changed, switch to the corresponding SoftKey menu called "active menu" and it will be drawn.
  3. Set and draw the labels for SoftKey, SELECT, LEFT, RIGHT, UP, and DOWN keys.
  4. Manage the elements of text, image, and 3-Color for each label.
  5. Receive the key event[SFEVT_KEY] from SoftKey and send it as the SoftKey event[SFEVT_RESPONDER_SOFTKEY] to the "active responder", which is the foremost one among responders currently bound with the SoftKey control.
[Note] About the focused responder

For more details on the focused responder, see State.

[Note] About the elements of text, image, and 3-Color for each label

The elements of text, image, and 3-Color for each label can be shared with different labels and each is managed by this unique key at the registration.

The frame color, the foreground color, and the background color are grouped together into 3-Color using the same unique color key at the registration. Conversely, 3-Color represents the frame color, the foreground color, and the background color.

How to use the SFZSoftKeyControl class

In the following description, the application class called "application" which contains two windows called "window1" and "window2" is supposed.

  1. Create the instance of the SoftKey control.

    // only one instance of SoftKey control per applet is valid
    _softkey = SFZSoftKeyControl::NewInstance(&error);
    
  2. Set the SoftKey control's parent to "application" [root(SFZRoot class)]. The SoftKey control is automatically placed foremost among the root's child responders by internal processing.

    // parent of SoftKey control must be application class
    _softkey->SetParent(application);
    
  3. Set the SoftKey control's style to "Standard"[default] or "Extention".

    // set SoftKey control's style to "Extention"
    _softkey->SetStyle(SFZSoftKeyControl::EXTENSION);
    
  4. Set the SoftKey control's real region.

    // calculate the suitable size automatically and set SoftKey control's real region to it
    _softkey->SetRealBound(_softkey->GetSuitableBound());
    
    [Caution] CAUTION

    In the GetSuitableBound() function of the SoftKey control, the rectangular region will be ignored if specified in the argument. The suitable rectangular region will be calculated from the full screen of the mobile phone gotten by calling the SFXDevice::GetScreenSize function.

    The normal GetSuitableBound() function will return only the size of the suitable rectangular region as a result of calculation. However, in case of the GetSuitableBound() function of the SoftKey control, it will return not only the size but also the origin position of the suitable rectangular region. Therefore, there is no need to set the origin position of the real region after calling the SFYResponder::GetSuitableBound function.

  5. Set the SoftKey control's state to "visible + active + disable + unfocus".

    // set SoftKey control's state to "visible + active + disable + unfocus" together
    _softkey->SetState(true, true, false, false);
    
  6. Register the elements of text, image, or 3-Color together with their keys for displaying the SoftKey control's labels.

    // register elements of text, image, and 3-Color with keys for displaying SoftKey control's labels
    // * keys for 3-Color(frame color, foreground color, background color) are same: KEY_COLOR
    _softkey->RegisterText(KEY_TEXT, text);                 // text
    _softkey->RegisterImage(KEY_IMAGE, image);              // image
    _softkey->RegisterFrameColor(KEY_COLOR, colorFrame);    // frame color
    _softkey->RegisterForeColor(KEY_COLOR, colorFore);      // foreground color
    _softkey->RegisterBackColor(KEY_COLOR, colorBack);      // background color
    
  7. Make the SoftKey menu with the specified menu key.

    [Note] Note
    The SoftKey menu can be shared with different responders and each is managed by this unique key at the registration.
    // make SoftKey control
    _softkey->CreateMenu(KEY_MENU);
    
  8. Register the keys of text, image, or color into the SoftKey menu.

    // set the text, image, and color for SoftKey1's label
    _softkey->SetTextKey(KEY_MENU, SFZSoftKeyControl::SOFTKEY_1, KEY_TEXT);
    _softkey->SetImageKey(KEY_MENU, SFZSoftKeyControl::SOFTKEY_1, KEY_IMAGE);
    _softkey->SetColorKey(KEY_MENU, SFZSoftKeyControl::SOFTKEY_1, KEY_COLOR);
    
  9. In the constructor of "window1", processing below is described.

    [Note] In case of the standard responder of SophiaFramework UNIVERSE

    When the constructor cannot be edited since it is the standard responder of SophiaFramework UNIVERSE such as SFZWindow or SFZTextMenu, the processing below is done externally.

    1. Get the instance of the SoftKey control.

      // get instance of SoftKey control
      _softkey = USRApplication::GetSoftKey();
      
      [Note] Note
      USRApplication::GetSoftKey() is supposed to be the function to get the instance of the SoftKey control.
    2. Bind "window1" with the SoftKey menu of the SoftKey control.

      // bind "window1" with SoftKey menu of SoftKey control
      _softkey->Bind(GetThis(), MENU_KEY);
      
    3. Register the handler for SoftKey event into "window1".

      [Note] Note
      It is necessary to declare and implement the handler of "OnSoftkey" for the SoftKey event.
      // register handler for SoftKey event into "window1"
      RegisterHandler(
          SFXEventRange(SFEVT_RESPONDER_SOFTKEY, SFEVT_RESPONDER_SOFTKEY, AVK_SOFT1, AVK_SOFT4),
          XANDLER_INTERNAL(OnSoftkey)
      );
      // * it is necessary to declare and implement handler of "OnSoftkey" for SoftKey event
      
    4. Unbind "window1" from the SoftKey control if its SoftKey menu will not have to be displayed from now on.

      // unbind "window1" from SoftKey control
      // code below can be omitted since "window1" will be automatically unbound when its state become "invalid"
      _softkey->UnBind(GetThis());
      
  10. For "window2", it is same as window1.
[Note] Mechanism of the SoftKey control

In the SoftKey control, the SoftKey menu can be associated with more than one responder.

The SoftKey control is defined as "active" if any of the responders bound with the SoftKey control is in the "focus" state. And the foremost responder among them is defined as "active responder".

At this time, the SoftKey menu associated with "active responder" will be displayed on the device screen. This menu is defined as "active menu".

The SoftKey control will transfer the key event[SFEVT_KEY] from SoftKey as SoftKey event[SFEVT_RESPONDER_SOFTKEY] to "active responder".

If the SoftKey control is not "active", the SoftKey event[SFEVT_RESPONDER_SOFTKEY] will be sent to no responder. And, the SoftKey menu whose menu key is "0", called "default menu", will be displayed on device the screen.

[Note] Default menu

Default menu is the SoftKey menu which will be displayed on the screen when any responder bound with the SoftKey control is in the "unfocus" state, i.e., "active responder" does not exist.

The default menu is automatically created and registered with the menu key "0" into the SoftKey control when its instance is created.

The initial settings of the default menu (menu key "0") is as follows:

  1. Foreground color: SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00)[white color]
  2. Background color: SFXRGBColor(0x77, 0x77, 0x77, 0x00)[gray color]
  3. Frame color: SFXRGBColor(0xDD, 0xDD, 0xDD, 0xDD)[light gray color]
  4. Label text: SFXWideString::EmptyInstance()
  5. Label image: SFBImageSmp::EmptyInstance()

*1 These value can be changed by updating each value for the menu key "0" with the functions of SFZSoftKeyControl.

*2 Since the enable flag of each label in the SoftKey menu is set to "true" by default, the label region will be displayed as it is. To undisplay a label region, set its enable flag to "false" with the SFZSoftKeyControl::SetEnable function.

[Note] About the SoftKey event

When the SoftKey control is used, the dispatching rule below will be automatically registered into the tracer of the application class by the internal processing of the SoftKey control as follows:

// when set SoftKey control's parent responder to application class
// dispatching rule below will be registered into the tracer
application->RegisterTracer(
                   SFXEventRange(SFEVT_KEY, SFEVT_KEY, AVK_SOFT1, AVK_SOFT4),
                   SFYTracer::ORDER_FORWARD, 
                   SFYTracer::STATE_ALL, 
                   false
);

The meaning of this dispatching rule is as follows:

  1. Distribute the key event from SoftKey to all child responders regardless of their state from foreground to background.
  2. If the event is handled, the event handling will stop there(the event will not be handled duplicately).

Since the SoftKey control is the child responder placed foremost of the application class[root (SFZRoot class)], the key event of SoftKey is always handled in the SoftKey control.

If the SoftKey control is "active", the key event of SoftKey will be transferred as the SoftKey event[SFEVT_RESPONDER_SOFTKEY] to the "active responder" defined above.

If the SoftKey control is not "active", the SoftKey event will not be sent to any responder.

Reference: Tracer | Handler | Root(Basic) | SFZRoot

Example 9.122. Define and make SoftKey control

// define screensaver_sfy application class
SFMTYPEDEFCLASS(screensaver_sfy)
class screensaver_sfy: public SFYApplication {
    SFMSEALCOPY(screensaver_sfy)
private:
    SFZSoftKeyControlSmp _softkey;  // SoftKey control must be defined as member variable of application class
    MainWindowSmp _main;
public:
    static SFCInvokerPtr Factory(Void);
    static SFZSoftKeyControlSmp GetSoftKey(Void);
private:
    explicit screensaver_sfy(Void) static_throws;
    virtual ~screensaver_sfy(Void);
    XANDLER_DECLARE_VOIDRENDER(OnRenderRequest)
};

// constructor of screensaver_sfy application class
screensaver_sfy::screensaver_sfy(Void) static_throws
{
    SFCError error;

    if (static_try()) {

        // .................

        if (static_try()) {

           // make SoftKey control
           // application class can have only one SoftKey control
           _softkey = SFZSoftKeyControl::NewInstance(&error);

           if (_softkey != null) {

                // set SoftKey control's parent responder to application class(root)
                // * SoftKey control must be root's child responder
                error = _softkey->SetParent(GetThis());

                // at this time, SoftKey control is automatically placed foremost among child responders of root by internal processing
                // key events of SoftKey are all handled in SoftKey control


                if (error == SFERR_NO_ERROR) {

                    // set SoftKey control's menu style to "extention style"
                    _softkey->SetStyle(SFZSoftKeyControl::EXTENSION);

                    // set real region to region automatically calculated from device screen size and SoftKey control style
                    // (to be set at the bottom in the device screen)
                    // *** CAUTION on specification of GetSuitableBound() only for SFZSoftKeyControl: 
                    // *** 1. A rectangular region will be ignored if specified in the argument and 
                    // ***    the suitable size will be calculated from the full screen region of the mobile phone gotten by calling SFXDevice::GetScreenSize().
                    // ***    In general, the argument is not specified since it has no meaning.
                    // *** 2. This function will return not only the suitable rectangle size but also the suitable origin position.
                    // ***    Therefore, there is no need to set the position of the real region after calling this function.
                    _softkey->SetRealBound(_softkey->GetSuitableBound());

                    // set SoftKey control's state to "visible" + "active" + "disable" + "unfocus" together
                    _softkey->SetState(true, true, false, false);

                    // move SoftKey control foremost
                    // _softkey->ToFront();  // this can be omitted since SoftKey control is always moved foremost by internal processing

                    // register each element (i.e., text, image, 3 colors) for SoftKey label
                    // before they are used for SoftKey menu
                    // * since image and 3 colors are not registered here, default setting are used for these elements
                    _softkey->RegisterText(KEY_TEXT_EXIT,   SFXWideString("End"));
                    _softkey->RegisterText(KEY_TEXT_EDIT,   SFXWideString("Set"));
                    _softkey->RegisterText(KEY_TEXT_ADD,    SFXWideString("Add"));
                    _softkey->RegisterText(KEY_TEXT_CHANGE, SFXWideString("Update"));
                    _softkey->RegisterText(KEY_TEXT_REMOVE, SFXWideString("Delete"));

                    // all elements can be registered together from the resource file
                    // _softkey->RegisterTextRange(
                    //   IDS_SK_EXIT, SFXPath(SCREENSAVER_SFY_RES_FILE), IDS_SK_EXIT, IDS_SK_REMOVE
                    // );
                }
            }
        }

        // make MainWindow
        if (error == SFERR_NO_ERROR) {
            _main = MainWindow::NewInstance(&error);

                .................

        }


        .................
    }
}


// implementation of function to get SoftKey control
SFZSoftKeyControlSmp screensaver_sfy::GetSoftKey(Void)
{
    return static_cast<screensaver_sfyPtr>(GetInstance())->_softkey;
}

Example 9.123. Set the SoftKey control in the responder class

// define MainWindow
SFMTYPEDEFRESPONDER(MainWindow)
class MainWindow: public SFZWindow {
    SFMSEALRESPONDER(MainWindow)
    SFMRESPONDERINSTANTIATEFOUR(MainWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
public:

        ................

private:
    SFZSoftKeyControlSmp _softkey;// SoftKey control

        ................

private:
    XANDLER_DECLARE_VOIDEVENT(OnKey)     // key handler
    XANDLER_DECLARE_VOIDEVENT(OnSoftkey) // SoftKey handler

        ................

};

// constructor of MainWindow
MainWindow::MainWindow(Void) static_throws
{
    static SFXEventRange::AtomRecConst range[] = {
        { SFEVT_APP_SUSPEND,       SFEVT_APP_SUSPEND,       SFP16_BEGIN,   SFP16_END },
        { SFEVT_APP_RESUME,        SFEVT_APP_RESUME,        SFP16_BEGIN,   SFP16_END },

        // normal key event
        { SFEVT_KEY,               SFEVT_KEY,               SFP16_BEGIN,   SFP16_END },

        // SoftKey event[SFEVT_RESPONDER_SOFTKEY] which SoftKey control will transfer
        // key event of SoftKey will be converted into SoftKey event[SFEVT_RESPONDER_SOFTKEY]
        { SFEVT_RESPONDER_SOFTKEY, SFEVT_RESPONDER_SOFTKEY, AVK_SOFT1,     AVK_SOFT4 }
    };
    SFYHandler::RuleRec rule[lengthof(range)];

    if (static_try()) {
        SetType(CODE_TYPE);

        rule[0].spp = XANDLER_FUNCTION(OnSuspend);
        rule[0].reference = this;
        rule[1].spp = XANDLER_FUNCTION(OnResume);
        rule[1].reference = this;

        // key handler
        rule[2].spp = XANDLER_FUNCTION(OnKey);
        rule[2].reference = this;

        // SoftKey handler
        rule[3].spp = XANDLER_FUNCTION(OnSoftkey);
        rule[3].reference = this;

        // register handlers
        static_throw(RegisterHandler(atomic_cast(range), rule, lengthof(range)));

        // get instance of SoftKey control
        if ((_softkey = screensaver_sfy::GetSoftKey()) != null) {

            if (!_softkey->ContainsMenuKey(MENUID_MAIN)) {
                // if SoftKey menu which corresponds to unique menu key "MENUID_MAIN" is not created

                // create SoftKey menu
                _softkey->CreateMenu(MENUID_MAIN);

                // set each element key to SoftKey menu above
                // * elements have already been registered in constructor of application class
                // keys below correspond to labels for SELECT, SOFTKEY_1, SOFTKEY_2, SOFTKEY_3, SOFTKEY_4 from left respectively
                UInt32 keyText[] = {
                    IDS_SK_EDIT, IDS_SK_EXIT, IDS_SK_ADD, IDS_SK_CHANGE, IDS_SK_REMOVE
                };
                _softkey->SetTextKey(MENUID_MAIN, keyText, lengthof(keyText));
           }

           // bind MainWindow with SoftKey menu of SoftKey control
           _softkey->Bind(this, MENUID_MAIN); 
           // or "_softkey->Bind(GetThis(), MENUID_MAIN);" *The former yields better performance than the latter.
        }
    }
}

Example 9.124. Implement the handler for the SoftKey event

// implement handler for SoftKey event: handler for key events from SoftKey1 to SoftKey4
// this handler will be booted up only if MainWindow is "active responder"
XANDLER_IMPLEMENT_VOIDEVENT(MainWindow, OnSoftkey, invoker, event)
{

                .................


    switch (event.GetP16()) {
        case AVK_SOFT1:
            // make the dialog which confirms termination

                .................

            break;
        case AVK_SOFT2:
            // make menu

                .................

}

9.18.21. Abstract Class which represents a Control [SFYControl]

SFYControl is the abstract base class for all controls.

All controls inherit from SFYControl, which contains a maximum value, a minimum value, and a current value. The contents of these values differ depending on the type of a control.(*1)

The concrete control is the part class which can be used as it is in the applet development. On the other hand, the abstract control is the base class to define and implement the user-defined control.

(*1)"minimum value ≦ current value ≦ maximum value" does not always stand up in all controls. For instance, the minimum value is always "0", and both of the current value and the maximum value are "-1" when no tab page exists in the SFYTabControl class.

In SFYControl, the following handlers(virtual functions) are registered for the region event[SFEVT_RESPONDER_BOUND] and the drawing event[SFEVT_RESPONDER_RENDER].

In a control inheriting from SFYControl, the following handlers(virtual functions) will be booted up first when the event is received.

Table 9.24. Events and their Handlers

Event Handler(Virtual function) Default behaviour Override
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REQUEST) event SFYWidget::HandleBoundRequest - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_OPTIMIZE) event SFYWidget::HandleBoundOptimize - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REAL) event SFYControl::HandleBoundReal Equalize the virtual region with the real region. *1 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_VIRTUAL) event SFYWidget::HandleBoundVirtual - Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_GLOBAL) event SFYWidget::HandleBoundGlobal - Optional
(SFEVT_RESPONDER_RENDER, SFP16_RENDER_REQUEST) event SFYWidget::HandleRenderRequest - Optional

* "-" in the default behaviour column represents that nothing is implemented.

[Note] NOTE

*1.SFYResponder::SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())) を実行します.In other words, equalize the virtual region with the real region.

The code to make the user-defined control is as follows:

Example 9.125. Declaration

SFMTYPEDEFRESPONDER(USRControl)
class USRControl: public SFYControl {
    SFMSEALRESPONDER(USRControl)
    SFMRESPONDERINSTANTIATETHREE(USRControl, SFYControl, SFYWidget, SFYResponder)
public:

    // define responder type
    // small alphabet and symbol must not be used since they are reserved for SophiaFramework UNIVERSE
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'C', 'N', 'T')
    };
    SFMTYPEDEFTYPE(CodeEnum)

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

    // virtual functions defined in the parent class and recommended to be implemented
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

Example 9.126. Implementation

USRControl::USRControl(Void) static_throws
{
    if (static_try()) {

        // set the responder type
        SetType(CODE_TYPE);

        // here describe the initialization
    }
}

USRControl::~USRControl(Void)
{
    // here describe the finalization
}

USRControlSmp USRControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRControl>(Factory(::new USRControl, exception));
}

Void USRControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // calculate the suitable control size
    // set the rectangle argument to the calculated suitable control size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    return;
}

Void USRControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // calculate the suitable control size within rectangular region given by the rectangle argument
    // set the rectangle argument to the calculated suitable control size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    return;
}

Void USRControl::HandleBoundVirtual(Void)
{
    // here describe the size recalculation if necessary when the virtual region is changed

    return;
}

Void USRControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // draw control

    return;
}

9.18.22. Abstract Class that Represents a Label Control [SFYLabelControl]

SFYLabelControl is the abstract base class to define and implement the user-defined label control.

In SFYLabelControl, functions to draw the focus border and manage the operation key are implemented by default. Several handlers with default behaviour are also implemented as virtual functions.

The operation key is set with the SFYLabelControl::SetOperateKey function. By default, the operation key is set to the SELECT key.

In SFYLabelControl, the following handlers(virtual functions) are registered for the key event[SFEVT_KEY] on the operation key, the region event[SFEVT_RESPONDER_BOUND], and the drawing event[SFEVT_RESPONDER_RENDER].

In a label control inheriting from SFYLabelControl, the following handlers(virtual functions) will be booted up first when the event is received.

Table 9.25. Events and their Handlers

Event Handler(Virtual function) Default behaviour Override
SFEVT_KEY event of the operation key set with SFYLabelControl::SetOperateKey SFYLabelControl::HandleOperateKey Send the result event *1 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REQUEST) event SFYWidget::HandleBoundRequest - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_OPTIMIZE) event SFYWidget::HandleBoundOptimize - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REAL) event SFYControl::HandleBoundReal Equalize the virtual region with the real region*2 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_VIRTUAL) event SFYWidget::HandleBoundVirtual - Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_GLOBAL) event SFYWidget::HandleBoundGlobal - Optional
(SFEVT_RESPONDER_RENDER, SFP16_RENDER_REQUEST) event SFYWidget::HandleRenderRequest - Optional

* "-" in the default behaviour column represents that nothing is implemented.

[Note] NOTE

*1. Execute SFYResponder::InvokeForward(SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, GetCurrentValue()), false).

*2. Execute SFYResponder::SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())). In other words, equalize the virtual region with the real region.

The code to make the user-defined label control is as follows:

Example 9.127. Declaration

SFMTYPEDEFRESPONDER(USRLabelControl)
class USRLabelControl: public SFYLabelControl {
    SFMSEALRESPONDER(USRLabelControl)
    SFMRESPONDERINSTANTIATEFOUR(USRLabelControl, SFYLabelControl, SFYControl, SFYWidget, SFYResponder)
public:

    // define responder type
    // small alphabet and symbol must not be used since they are reserved for SophiaFramework UNIVERSE
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'L', 'B', 'L')
    };
    SFMTYPEDEFTYPE(CodeEnum)

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

    // virtual functions defined in the parent class and recommended to be implemented
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

Example 9.128. Implementation

USRLabelControl::USRLabelControl(Void) static_throws
{
    if (static_try()) {

        // set the responder type
        SetType(CODE_TYPE);

        // in general, set transparency attribute to "true" since label control does not have background
        SetPropertyTransparent(true);

        // here describe the initialization
    }
}

USRLabelControl::~USRLabelControl(Void)
{
    // here describe the finalization
}

USRLabelControlSmp USRLabelControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRLabelControl>(Factory(::new USRLabelControl, exception));
}

Void USRLabelControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // in case of using function of SFYLabelControl class to draw focus border [i.e., SFYLabelControl::DrawFocus()],
    // deflate rectangle by size of focus border
    rectangle->Deflate(GetFocusMargin());

    // calculate the suitable focus border size
    // set the rectangle argument to the calculated suitable focus border size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    // in case of using function of SFYLabelControl class to draw focus border [i.e., SFYLabelControl::DrawFocus()],
    // inflate rectangle by size of focus border
    rectangle->Inflate(GetFocusMargin());

    return;
}

Void USRLabelControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // in case of using function of SFYLabelControl class to draw focus border [i.e., SFYLabelControl::DrawFocus()],
    // deflate rectangle by size of focus border
    rectangle->Deflate(GetFocusMargin());

    // calculate the suitable focus border size within rectangular region given by the rectangle argument
    // set the rectangle argument to the calculated suitable focus border size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    // in case of using function of SFYLabelControl class to draw focus border [i.e., SFYLabelControl::DrawFocus()],
    // inflate rectangle by size of focus border
    rectangle->Inflate(GetFocusMargin());

    return;
}

Void USRLabelControl::HandleBoundVirtual(Void)
{
    // here describe the size recalculation if necessary when the virtual region is changed

    return;
}

Void USRLabelControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // in case of using function of SFYLabelControl class to draw focus border [i.e., SFYLabelControl::DrawFocus()],
    // draw focus border as below
    DrawFocus(graphics, GetLocalBound());

    // draw inside focus border

    return;
}

9.18.23. Abstract Class that Represents a Box Control [SFYBoxControl]

SFYBoxControl is the abstract base class to define and implement the user-defined box control.

In SFYBoxControl, functions to draw the box and manage the operation key are implemented by default. Several handlers with default behaviour are also implemented as virtual functions.

The operation key is set with the SFYBoxControl::SetOperateKey function. By default, the operation key is set to the SELECT key.

In SFYBoxControl, the following handlers(virtual functions) are registered for the key event[SFEVT_KEY] on the operation key, the region event[SFEVT_RESPONDER_BOUND], and the drawing event[SFEVT_RESPONDER_RENDER].

In a box control inheriting from SFYBoxControl, the following handlers(virtual functions) will be booted up first when the event is received.

Table 9.26. Events and their Handlers

Event Handler(Virtual function) Default behaviour Override
SFEVT_KEY event of the operation key set with SFYBoxControl::SetOperateKey SFYBoxControl::HandleOperateKey Send the result event *1 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REQUEST) event SFYWidget::HandleBoundRequest - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_OPTIMIZE) event SFYWidget::HandleBoundOptimize - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REAL) event SFYControl::HandleBoundReal Equalize the virtual region with the real region*2 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_VIRTUAL) event SFYWidget::HandleBoundVirtual - Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_GLOBAL) event SFYWidget::HandleBoundGlobal - Optional
(SFEVT_RESPONDER_RENDER, SFP16_RENDER_REQUEST) event SFYWidget::HandleRenderRequest - Optional

* "-" in the default behaviour column represents that nothing is implemented.

[Note] NOTE

*1. Execute SFYResponder::InvokeForward(SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, GetCurrentValue()), false).

*2. Execute SFYResponder::SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())). In other words, equalize the virtual region with the real region.

The code to make the user-defined box control is as follows:

Example 9.129. Declaration

SFMTYPEDEFRESPONDER(USRBoxControl)
class USRBoxControl: public SFYBoxControl {
    SFMSEALRESPONDER(USRBoxControl)
    SFMRESPONDERINSTANTIATEFOUR(USRBoxControl, SFYBoxControl, SFYControl, SFYWidget, SFYResponder)
public:

    // define responder type
    // small alphabet and symbol must not be used since they are reserved for SophiaFramework UNIVERSE
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'B', 'O', 'X')
    };
    SFMTYPEDEFTYPE(CodeEnum)

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

    // virtual functions defined in the parent class and recommended to be implemented
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

Example 9.130. Implementation

USRBoxControl::USRBoxControl(Void) static_throws
{
    if (static_try()) {

        // set the responder type
        SetType(CODE_TYPE);

        // here describe the initialization
    }
}

USRBoxControl::~USRBoxControl(Void)
{
    // here describe the finalization
}

USRBoxControlSmp USRBoxControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRBoxControl>(Factory(::new USRBoxControl, exception));
}

Void USRBoxControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // in case of using function of SFYBoxControl class to draw box [i.e., SFYBoxControl::DrawBox()],
    // deflate rectangle by size of box margin
    rectangle->Deflate(GetBoxMargin());

    // calculate the suitable box size
    // set the rectangle argument to the calculated suitable box size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    // in case of using function of SFYBoxControl class to draw box [i.e., SFYBoxControl::DrawBox()],
    // inflate rectangle by size of box margin
    rectangle->Inflate(GetBoxMargin());

    return;
}

Void USRBoxControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // in case of using function of SFYBoxControl class to draw box [i.e., SFYBoxControl::DrawBox()],
    // deflate rectangle by size of box margin
    rectangle->Deflate(GetBoxMargin());

    // calculate the suitable box size within rectangular region given by the rectangle argument
    // set the rectangle argument to the calculated suitable box size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    // in case of using function of SFYBoxControl class to draw box [i.e., SFYBoxControl::DrawBox()],
    // inflate rectangle by size of box margin
    rectangle->Inflate(GetBoxMargin());

    return;
}

Void USRBoxControl::HandleBoundVirtual(Void)
{
    // here describe the size recalculation if necessary when the virtual region is changed

    return;
}

Void USRBoxControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // in case of using function of SFYBoxControl class to draw box [i.e., SFYBoxControl::DrawBox()],
    // draw box as below
    DrawBox(graphics, GetLocalBound());

    // draw inside box

    return;
}

9.18.24. Abstract Class that Represents a Button Control [SFYButtonControl]

SFYButtonControl is the abstract base class to define and implement the user-defined button control.

In SFYButtonControl, functions to draw the button and manage the operation key are implemented by default. Several handlers with default behaviour are also implemented as virtual functions.

The operation key is set with the SFYButtonControl::SetOperateKey function. By default, the operation key is set to the SELECT key.

In SFYButtonControl, the following handlers(virtual functions) are registered for the key event[SFEVT_KEY] on the operation key, the region event[SFEVT_RESPONDER_BOUND], and the drawing event[SFEVT_RESPONDER_RENDER].

In a button control inheriting from SFYButtonControl, the following handlers(virtual functions) will be booted up first when the event is received.

Table 9.27. Events and their Handlers

Event Handler(Virtual function) Default behaviour Override
SFEVT_KEY event of the operation key set with SFYButtonControl::SetOperateKey SFYButtonControl::HandleOperateKey - Optional
SFEVT_KEY_PRESS event of the operation key set with SFYButtonControl::SetOperateKey SFYButtonControl::HandleOperateKeyPress - Optional
SFEVT_KEY_RELEASE event of the operation key set with SFYButtonControl::SetOperateKey SFYButtonControl::HandleOperateKeyRelease Send the result event *1 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REQUEST) event SFYWidget::HandleBoundRequest - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_OPTIMIZE) event SFYWidget::HandleBoundOptimize - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REAL) event SFYControl::HandleBoundReal Equalize the virtual region with the real region *2 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_VIRTUAL) event SFYWidget::HandleBoundVirtual - Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_GLOBAL) event SFYWidget::HandleBoundGlobal - Optional
(SFEVT_RESPONDER_RENDER, SFP16_RENDER_REQUEST) event SFYWidget::HandleRenderRequest - Optional

* "-" in the default behaviour column represents that nothing is implemented.

[Note] NOTE

*1. Execute SFYResponder::InvokeForward(SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, GetCurrentValue()), false).

*2. Execute SFYResponder::SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())). In other words, equalize the virtual region with the real region.

The code to make the user-defined button control is as follows:

Example 9.131. Declaration

SFMTYPEDEFRESPONDER(USRButtonControl)
class USRButtonControl: public SFYButtonControl {
    SFMSEALRESPONDER(USRButtonControl)
    SFMRESPONDERINSTANTIATEFOUR(USRButtonControl, SFYButtonControl, SFYControl, SFYWidget, SFYResponder)
public:

    // define responder type
    // small alphabet and symbol must not be used since they are reserved for SophiaFramework UNIVERSE
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'B', 'T', 'N')
    };
    SFMTYPEDEFTYPE(CodeEnum)

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

    // virtual functions defined in the parent class and recommended to be implemented
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

Example 9.132. Implementation

USRButtonControl::USRButtonControl(Void) static_throws
{
    if (static_try()) {

        // set the responder type
        SetType(CODE_TYPE);

        // here describe the initialization
    }
}

USRButtonControl::~USRButtonControl(Void)
{
    // here describe the finalization
}

USRButtonControlSmp USRButtonControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRButtonControl>(Factory(::new USRButtonControl, exception));
}

Void USRButtonControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // in case of using function of SFYButtonControl class to draw button and shadow [i.e., SFYButtonControl::DrawButton()/DrawShadow()],
    // deflate rectangle by size of button and shadow
    rectangle->Deflate(GetShadowMargin());
    rectangle->Deflate(GetButtonMargin());

    // calculate the suitable button size
    // set the rectangle argument to the calculated suitable button size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    // in case of using function of SFYButtonControl class to draw button and shadow [i.e., SFYButtonControl::DrawButton()/DrawShadow()],
    // inflate rectangle by size of button and shadow
    rectangle->Inflate(GetButtonMargin());
    rectangle->Inflate(GetShadowMargin());

    return;
}

Void USRButtonControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // in case of using function of SFYButtonControl class to draw button and shadow [i.e., SFYButtonControl::DrawButton()/DrawShadow()],
    // deflate rectangle by size of button and shadow
    rectangle->Deflate(GetShadowMargin());
    rectangle->Deflate(GetButtonMargin());

    // calculate the suitable button size within rectangular region given by the rectangle argument
    // set the rectangle argument to the calculated suitable button size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    // in case of using function of SFYButtonControl class to draw button and shadow [i.e., SFYButtonControl::DrawButton()/DrawShadow()],
    // inflate rectangle by size of button and shadow
    rectangle->Inflate(GetButtonMargin());
    rectangle->Inflate(GetShadowMargin());

    return;
}

Void USRButtonControl::HandleBoundVirtual(Void)
{
    // here describe the size recalculation if necessary when the virtual region is changed

    return;
}

Void USRButtonControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // in case of using function of SFYButtonControl class to draw button and shadow [i.e., SFYButtonControl::DrawButton()/DrawShadow()],
    // draw button and shadow as below
    DrawButton(graphics, DrawShadow(graphics, GetLocalBound()));

    // draw inside button

    return;
}

9.18.25. Abstract Class that Represents a Check Box Control [SFYCheckboxControl]

SFYCheckboxControl is the abstract base class to define and implement the user-defined check box control.

In SFYCheckboxControl, functions to draw the check box, switch the checked state and manage the operation key are implemented by default. Several handlers with default behaviour are also implemented as virtual functions.

The operation key is set with the SFYButtonControl::SetOperateKey function. By default, the operation key is set to the SELECT key.

In SFYCheckboxControl, the following handlers(virtual functions) are registered for the key event[SFEVT_KEY] on the operation key, the region event[SFEVT_RESPONDER_BOUND], and the drawing event[SFEVT_RESPONDER_RENDER].

In a check box control inheriting from SFYCheckboxControl, the following handlers(virtual functions) will be booted up first when the event is received.

Table 9.28. Events and their Handlers

Event Handler(Virtual function) Default behaviour Override
SFEVT_KEY event of the operation key set with SFYButtonControl::SetOperateKey SFYButtonControl::HandleOperateKey - Optional
SFEVT_KEY_PRESS event of the operation key set with SFYButtonControl::SetOperateKey SFYButtonControl::HandleOperateKeyPress - Optional
SFEVT_KEY_RELEASE event of the operation key set with SFYButtonControl::SetOperateKey SFYCheckboxControl::HandleOperateKeyRelease Send the result event of switching the checked state *1 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REQUEST) event SFYWidget::HandleBoundRequest - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_OPTIMIZE) event SFYWidget::HandleBoundOptimize - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REAL) event SFYControl::HandleBoundReal Equalize the virtual region with the real region *2 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_VIRTUAL) event SFYWidget::HandleBoundVirtual - Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_GLOBAL) event SFYWidget::HandleBoundGlobal - Optional
(SFEVT_RESPONDER_RENDER, SFP16_RENDER_REQUEST) event SFYWidget::HandleRenderRequest - Optional

* "-" in the default behaviour column represents that nothing is implemented.

[Note] NOTE

*1. After switching the checked state, execute SFYResponder::InvokeForward(SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, GetCurrentValue()), false).

*2. Execute SFYResponder::SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())). In other words, equalize the virtual region with the real region.

The code to make the user-defined check box control is as follows:

Example 9.133. Declaration

SFMTYPEDEFRESPONDER(USRCheckboxControl)
class USRCheckboxControl: public SFYCheckboxControl {
    SFMSEALRESPONDER(USRCheckboxControl)
    SFMRESPONDERINSTANTIATEFIVE(USRCheckboxControl, SFYCheckboxControl, SFYButtonControl, SFYControl, SFYWidget, SFYResponder)
public:

    // define responder type
    // small alphabet and symbol must not be used since they are reserved for SophiaFramework UNIVERSE
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'C', 'H', 'K')
    };
    SFMTYPEDEFTYPE(CodeEnum)

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

    // virtual functions defined in the parent class and recommended to be implemented
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

Example 9.134. Implementation

USRCheckboxControl::USRCheckboxControl(Void) static_throws
{
    if (static_try()) {

        // set the responder type
        SetType(CODE_TYPE);

        // since check box control's label doesn't have background, set true to transparent mode
        SetPropertyTransparent(true);

        // here describe the initialization
    }
}

USRCheckboxControl::~USRCheckboxControl(Void)
{
    // here describe the finalization
}

USRCheckboxControlSmp USRCheckboxControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRCheckboxControl>(Factory(::new USRCheckboxControl, exception));
}

Void USRCheckboxControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // calculate the suitable check box control size
    // set the rectangle argument to the calculated suitable check box control size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    return;
}

Void USRCheckboxControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // calculate the suitable check box control size within rectangular region given by the rectangle argument
    // set the rectangle argument to the calculated suitable check box control size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    return;
}

Void USRCheckboxControl::HandleBoundVirtual(Void)
{
    // here describe the size recalculation if necessary when the virtual region is changed

    return;
}

Void USRCheckboxControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    SFXGrid grid;

    // in case of using function of SFYCheckboxControl class to draw check box and shadow [i.e., SFYCheckboxControl::DrawButton**()/DrawShadow**()/DrawCheckmark**()],
    // draw check box, shadow, and check mark as below

    // _height variable is hight of check box 
    // _origin variable is origin of check box
    // * these variable is calculated with font hight used for label

    if (_height >= 28) {

        grid.Set(DrawShadow28(graphics, _origin));
        DrawButton27(graphics, grid);
        grid.Add(3, 3);
        DrawCheckmark21(graphics, grid);
    }
    else if (_height >= 14) {

        grid.Set(DrawShadow14(graphics, _origin));
        DrawButton13(graphics, grid);
        grid.Add(2, 2);
        DrawCheckmark09(graphics, grid);
    }

    // draw check box control's label

    return;
}

9.18.26. Abstract Class that Represents a Radio Button Control [SFYRadiobuttonControl]

SFYRadiobuttonControl is the abstract base class to define and implement the user-defined radio button control.

In SFYRadiobuttonControl, functions to draw the check box, switch the checked state exclusively and manage the operation key are implemented by default. Several handlers with default behaviour are also implemented as virtual functions.

The operation key is set with the SFYButtonControl::SetOperateKey function. By default, the operation key is set to the SELECT key.

In SFYRadiobuttonControl, the following handlers(virtual functions) are registered for the key event[SFEVT_KEY] on the operation key, the region event[SFEVT_RESPONDER_BOUND], and the drawing event[SFEVT_RESPONDER_RENDER].

In a radio button control inheriting from SFYRadiobuttonControl, the following handlers(virtual functions) will be booted up first when the event is received.

Table 9.29. Events and their Handlers

Event Handler(Virtual function) Default behaviour Override
SFEVT_KEY event of the operation key set with SFYButtonControl::SetOperateKey SFYButtonControl::HandleOperateKey - Optional
SFEVT_KEY_PRESS event of the operation key set with SFYButtonControl::SetOperateKey SFYButtonControl::HandleOperateKeyPress - Optional
SFEVT_KEY_RELEASE event of the operation key set with SFYButtonControl::SetOperateKey SFYRadiobuttonControl::HandleOperateKeyRelease Send the result event of switching the checked state exclusively *1 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REQUEST) event SFYWidget::HandleBoundRequest - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_OPTIMIZE) event SFYWidget::HandleBoundOptimize - Recommended
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_REAL) event SFYControl::HandleBoundReal Equalize the virtual region with the real region *2 Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_VIRTUAL) event SFYWidget::HandleBoundVirtual - Optional
(SFEVT_RESPONDER_BOUND, SFP16_BOUND_GLOBAL) event SFYWidget::HandleBoundGlobal - Optional
(SFEVT_RESPONDER_RENDER, SFP16_RENDER_REQUEST) event SFYWidget::HandleRenderRequest - Optional

* "-" in the default behaviour column represents that nothing is implemented.

[Note] NOTE

*1. After switching the checked state exclusively, execute SFYResponder::InvokeForward(SFXEvent(SFEVT_RESPONDER_RESULT, SFP16_RESULT_OK, GetCurrentValue()), false).

*2. Execute SFYResponder::SetVirtualBound(SFXRectangle(SFXGrid::ZeroInstance(), GetRealBound().GetSize())). In other words, equalize the virtual region with the real region.

The code to make the user-defined radio button is as follows:

Example 9.135. Declaration

SFMTYPEDEFRESPONDER(USRRadiobuttonControl)
class USRRadiobuttonControl: public SFYRadiobuttonControl {
    SFMSEALRESPONDER(USRRadiobuttonControl)
    SFMRESPONDERINSTANTIATESIX(USRRadiobuttonControl, SFYRadiobuttonControl, SFYCheckboxControl, SFYButtonControl, SFYControl, SFYWidget, SFYResponder)
public:

    // define responder type
    // small alphabet and symbol must not be used since they are reserved for SophiaFramework UNIVERSE
    enum CodeEnum {
        CODE_TYPE = four_char_code('U', 'R', 'D', 'O')
    };
    SFMTYPEDEFTYPE(CodeEnum)

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

    // virtual functions defined in the parent class and recommended to be implemented
    virtual Void HandleBoundRequest(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundOptimize(SFXRectanglePtr rectangle) const;
    virtual Void HandleBoundVirtual(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
};

Example 9.136. Implementation

USRRadiobuttonControl::USRRadiobuttonControl(Void) static_throws
{
    if (static_try()) {

        // set the responder type
        SetType(CODE_TYPE);

        // since radio button control's label doesn't have background, set true to transparent mode
        SetPropertyTransparent(true);

        // here describe the initialization
    }
}

USRRadiobuttonControl::~USRRadiobuttonControl(Void)
{
    // here describe the finalization
}

USRRadiobuttonControlSmp USRRadiobuttonControl::NewInstance(SFCErrorPtr exception)
{
    return static_pointer_cast<USRRadiobuttonControl>(Factory(::new USRRadiobuttonControl, exception));
}

Void USRRadiobuttonControl::HandleBoundRequest(SFXRectanglePtr rectangle) const
{
    // calculate the suitable radio button control size
    // set the rectangle argument to the calculated suitable radio button control size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    return;
}

Void USRRadiobuttonControl::HandleBoundOptimize(SFXRectanglePtr rectangle) const
{
    // calculate the suitable radio button control size within rectangular region given by the rectangle argument
    // set the rectangle argument to the calculated suitable radio button control size
    // for the rectangle argument, it is recommended to set only its size and not to change its origin in this function

    return;
}

Void USRRadiobuttonControl::HandleBoundVirtual(Void)
{
    // here describe the size recalculation if necessary when the virtual region is changed

    return;
}

Void USRRadiobuttonControl::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    SFXGrid grid;

    // in case of using function of SFYRadiobuttonControl class to draw radio button and shadow [i.e., SFYRadiobuttonControl::DrawButton**()/DrawShadow**()/DrawCheckmark**()],
    // draw radio button and shadow as below

    // _height variable is hight of radio button 
    // _origin variable is origin of radio button
    // * these variable is calculated with font hight used for label

    if (_height >= 28) {

        grid.Set(DrawShadow28(graphics, _origin));
        DrawButton27(graphics, grid);
        grid.Add(8, 8);
        DrawCheckmark11(graphics, grid);
    }
    else if (_height >= 14) {

        grid.Set(DrawShadow14(graphics, _origin));
        DrawButton13(graphics, grid);
        grid.Add(4, 4);
        DrawCheckmark05(graphics, grid);
    }

    // draw radio button control's label

    return;
}