PrevNextUpHome SophiaFramework UNIVERSE 5.3

3.3. Control(Basic)

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

SFYControl is the abstract base class for all controls.

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

In this section, controls such as a text button control, a check box control, a radio button control, a label control, an edit box control, a radio button control, a combo box control, or a list box control will be described.

3.3.1. Button Control

Let's make three text button controls(SFZTextButtonControl) as the figure below.

Figure 3.5. Button control

Button control

  1. Button control 1("OK" button) and button control 2("NG" button) execute exclusively.
  2. Button control 3("ON/OFF" button) is the switching button to display "Hello Window".

The following is the code to declare the button control and its handler.

Example 3.15. Declare the button control and its handler

// define the MyWindow class
SFMTYPEDEFRESPONDER(MyWindow)  //  macro to generate the useful types
class MyWindow : public SFZWindow
{
    SFMSEALRESPONDER(MyWindow)  //  macro to prohibit the developer from copying this instance

    // macro to specify the inheritance relation from SFYResponder to this class
    SFMRESPONDERINSTANTIATEFOUR(MyWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)

public:

    enum CodeEnum {
        CODE_TYPE = four_char_code('M', 'W', 'N', 'D')
    };
    SFMTYPEDEFTYPE(CodeEnum)

private:

    // *** added code segments are in bold

    // declare the  button controls
    SFZTextButtonControlSmp _button1;
    SFZTextButtonControlSmp _button2;
    SFZTextButtonControlSmp _button3;

    // switch to display "Hello Window"
    Bool _flagShowHw; 

public:

    static MyWindowSmp NewInstance(SFCErrorPtr exception = null);

    // make various controls in MyWindow
    SFCError Make(Void);

protected:

    explicit MyWindow(Void) static_throws;
    virtual ~MyWindow(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;

private:

    // make the button controls
    SFCError CreateButtons(SFXGridPtr offs);

    // declare the key handler 
    XANDLER_DECLARE_BOOLEVENT(OnKey)            

    // declare the result handler for the button control 1 and 2
    XANDLER_DECLARE_VOIDRESULT(OnButton12)

    // declare the result handler for the button control 3
    XANDLER_DECLARE_VOIDRESULT(OnButton3)
};
[Note] Drawing processing of the standard responder of SophiaFramework UNIVERSE

In case of standard SophiaFramework UNIVERSE responder such as SFZTextButtonControl, it will be drawn automatically after instantiation if the parent responder, real region, state, and other necessary parameters are set.

[Note] Declaration and implementation of the result handler

The result handler is declared / implemented with the XANDLER_DECLARE_VOIDRESULT / XANDLER_IMPLEMENT_VOIDRESULT macro.

[Note] Moving the focus

You don't have to describe moving the focus among controls in MyWindow.

This processing has already been implemented in the SFYContainer::ScrollUp / SFYContainer::ScrollDown function of the SFYContainer class which the MyWindow class inherits from.

By default, the focus will be moved to the previous or the next control with the UP or DOWN key respectively.

Key settings for moving the focus can be changed with the SFYContainer::SetScrollUpKey / SFYContainer::SetScrollDownKey function.

Reference: Container(Basic)

The following is the code to make and place three button controls in MyWindow.

Example 3.16. Make the various controls in MyWindow

#define X_MARGIN    8  // button control 1: origin of the real region(X coordinate)
#define Y_MARGIN    8  // button control 1: origin of the real region(Y coordinate)

enum {
    ID_BUTTON1 = 1,    // button control 1's ID
    ID_BUTTON2         // button control 2's ID
};

// make various controls in MyWindow
SFCError MyWindow::Make(Void)
{
    // left-top of the drawing region of MyWindow
    SFXGrid offset(X_MARGIN, Y_MARGIN);

    SFCError error(SFERR_NO_ERROR);

    //  make the button controls in MyWindow
    if ((error = CreateButtons(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    return error;
}

Next, let's make the button controls in MyWindow.

In this code, properties of the button control such as a label text or an ID are set.

Example 3.17. Make the button controls

// make the button controls
SFCError MyWindow::CreateButtons(SFXGridPtr offs)
{
    SFXGraphicsPtr graphics = SFXGraphics::GetInstance();
    SInt16Const height = graphics->GetFontHeight() + 4;                  // button control's height
    SInt16Const width = (GetLocalBound().GetWidth() - 4 * X_MARGIN) / 3; // button control's width
    SFXRectangle rect(*offs, SFXSize(width, height));                    // button control 1's real region 
    SFCError error(SFERR_NO_ERROR);

    // make the button control 1
    if ((_button1 = SFZTextButtonControl::NewInstance(&error)) != null) {

        // set the button control 1's parent responder to MyWindow
        error = _button1->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

            // register the result handler into the button control 1
            error = _button1->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnButton12)
            );

            if (error == SFERR_NO_ERROR) {

                // set the label of the button control 1 to "OK"
                error = _button1->SetText("OK");

                if (error == SFERR_NO_ERROR) {

                    // set the button control 1's ID
                    _button1->SetID(ID_BUTTON1);

                    // set the button control 1's real region
                    _button1->SetRealBound(rect);

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

                    // it is unnecessary to call ToFront() of the button control
                }
            }
        }
    }

    // make the button control 2
    if ((_button2 = SFZTextButtonControl::NewInstance(&error)) != null) {

        // set the button control 2's parent responder to MyWindow
        error = _button2->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

            // register the result handler into the button control 2
            error = _button2->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnButton12)
            );

            if (error == SFERR_NO_ERROR) {

                // set the label of the button control 2 to "NG"
                error = _button2->SetText("NG");

                if (error == SFERR_NO_ERROR) {

                    // set the button control 2's ID
                    _button2->SetID(ID_BUTTON2);

                    // calculate the button control 2's real region
                    rect.Offset(X_MARGIN + rect.GetWidth(), 0);

                    // set the button control 2's real region
                    _button2->SetRealBound(rect);

                    // set the button control 2's state to "visible" + "inactive" + "disable" + "unfocus" together 
                    _button2->SetState(true, false, false, false);
                }
            }
        }
    }

    // make the button control 3
    if ((_button3 = SFZTextButtonControl::NewInstance(&error)) != null) {

        // set the button control 3's to parent responder MyWindow
        error = _button3->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

            // register the result handler into the button control 3
            error = _button3->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnButton3)
            );

            if (error == SFERR_NO_ERROR) {

                // set the label of the button control 3 to "Off"
                error = _button3->SetText("Off");

                if (error == SFERR_NO_ERROR) {

                    // calculate the button control 3's real region
                    rect.Offset(X_MARGIN + rect.GetWidth(), 0);

                    // set the button control 3's real region
                    _button3->SetRealBound(rect);

                    // set the button control 3's state to "visible" + "active" + "enable" + "unfocus" together 
                    _button3->SetState(true, true, true, false);
                }
            }
        }
    }

    // update the offset
    offs->AddY(rect.GetHeight() + Y_MARGIN);

    return error;
}
[Note] Register the result handler into the button control

The button control will receive the result event when the operation key is pressed.

To register the result handler into the button control, use the SFYResponder::RegisterHandler function.

Reference: Result Event[SFEVT_RESPONDER_RESULT] | Handler for the Result Event[XANDLER_DECLARE_VOIDRESULT]

[Note] Operation key

Button control is operated with the operation key, which is set to the SELECT key by default.

Setting of The operation key can be changed with the SFYButtonControl::SetOperateKey function.

[Important] SFYResponder::ToFront function

The SFYResponder::ToFront function is used to move foremost a responder such as a window, a dialog, a menu.

If the SFYResponder::ToFront function of the parent responder is called, the child responders such as control will be automatically moved foremost.

Reference: SFXGraphics | SFXRectangle | SFXGrid | SFXSize | Shape and Color

After the statement below is executed in the helloworld::Make(), three button controls will be created and placed in MyWindow.

_myWindow->Make();

Example 3.18. Make MyWindow

// make MyWindow
SFCError helloworld::Make(Void)
{
    SFCError error(SFERR_NO_ERROR);
    if ((_myWindow = MyWindow::NewInstance(&error)) != null) {
        error = _myWindow->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {

            // set the MyWindow's real region to the region obtained by deflating the device screen region by (15,20)
            _myWindow->SetRealBound(GetLocalBound().Deflate(15, 20));

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

            // move MyWindow foremost
            _myWindow->ToFront();

            // *** added code segments are in bold

            // make three button controls in MyWindow 
            _myWindow->Make();
        }
    }
    return error;
}

In the constructor of MyWindow, the "Hello Window" string will be displayed by default by setting the _ifShowHw flag to "true".

Example 3.19. Constructor of MyWindow

// constructor
// *** updated code segments are in bold
MyWindow::MyWindow(Void) : _ifShowHw(true) static_throws // set _ifShowHw flag indicating whether or not to display string to "true"
{
    if (static_try()) {

        // set the responder type
        SetType(CODE_TYPE);

        // register the key handler into MyWindow
        static_throw(RegisterHandler(
            SFXEventRange(SFEVT_KEY, SFEVT_KEY, SFP16_BEGIN, SFP16_END),
            XANDLER_INTERNAL(OnKey)
        ));
    }
}

The following is the code to implement the result handler, which will be booted up when the button control is operated.

Each result handler of the button control 1 and button control 2 makes other state active or inactive exclusively.

Example 3.20. Implement the result handler of the button control 1 and 2

// implement the result handler of the button control 1 and 2
XANDLER_IMPLEMENT_VOIDRESULT(MyWindow, OnButton12, invoker, reason, result)
{
    unused(reason);
    unused(result);

    // get the pressed button control
    // downcast into SFZTextButtonControlPtr type since invoker is of SFYResponderPtr type
    SFZTextButtonControlPtr pushed(static_cast<SFZTextButtonControlPtr>(invoker));

    // get the unpressed button control
    UInt32 pairID = (pushed->GetID() == ID_BUTTON1) ? ID_BUTTON2 : ID_BUTTON1;
    SFZTextButtonControlSmp pair = static_pointer_cast<SFZTextButtonControl>(GetThis()->GetChildFront(pairID));

    // set the pressed button control's label to "NG"
    pushed->SetText("NG");

    // set only the active state of the pressed button control to "false" (i.e., inactive)
    // since active state has higher priority than enable or focus state
    pushed->SetStateActive(false);

    // set the unpressed button control's label to "OK"
    pair->SetText("OK");

    // set the unpressed button control's state to "active" + "enable" + "focus"
    pair->SetStateActive(true);
    pair->SetStateEnable(true);
    pair->SetStateFocus(true);

    return;
}

For the button control 1 and the button control 2, their IDs are set with the SFYResponder::SetID function.

The ID of the responder can be obtained by calling the SFYResponder::GetID function. And the responder can be searched with the SFYResponder::GetChildFront function.

If there are multiple child responders which have the same ID, the foremost responder among them will be returned when the SFYResponder::GetChildFront function is called.

For more details, see ID.

The invoker argument is the pointer of the SFYResponderPtr type to the responder which calls this handler.

To set the button control's label with the SFZTextButtonControl::SetText function, this pointer must be of the SFZTextButtonControlPtr type.

Therefore this pointer needs to be downcasted from the SFYResponderPtr type into the SFZTextButtonControlPtr type with the static_cast operator.

[Caution] Downcast operator for smart pointer

Since the return value of the SFYResponder::GetChildFront function is of the SFYResponderSmp type, it is downcasted into the SFZTextButtonControlSmp type with the static_pointer_cast operator.

[Note] State of the responder

There are 5 kind of states [i.e., valid, visible, active, enable, and focus states] in the responder.

With the SFYResponder::SetState function, 4 kinds of state flags [i.e., visible, active, enable, and focus states] can be set together. The valid state flag is set to "true" or "false" with the SFYResponder::Initialize or SFYResponder::Terminate function respectively.

For more details, see State.

Button control 3 switches on and off the _flagShowHw flag indicating whether or not to display the "Hello Window" string.

Example 3.21. Implement the result handler of the button control 3

// implement the result handler of the button control 3
XANDLER_IMPLEMENT_VOIDRESULT(MyWindow, OnButton3, invoker, reason, result)
{
    unused(invoker);
    unused(reason);
    unused(result);

    // switch from "Off" to "On" vice versa for the button control 3's label
    _ifShowHw = !_ifShowHw;
    _button3->SetText(_ifShowHw ? "Off" : "On");

    // register MyWindowMyWindow's real region as the redraw region
    Invalidate(); 

    // when nothing is specified as the argument of Invalidate(), MyWindow's real region is registered as the redraw region

    return;
}
[Note] Redrawing the responder

Redrawing the responder is performed once together with all responders in the responder tree at the end of each event loop.

Concretely, redrawing processing of the responder is as follows:

The event loop starts at sending the BREW-defined event to the root responder[by default, root[SFZRoot]], which the application class contains at the top of the responder tree by default.

The event is distributed to the responders in the responder tree according to the tracer rule registered into the distributer and the responder.

While the event is being distributed, the appropriate handler is called if necessary.

Though the responder needs to be redrawn when the text, background color, or visible state is changed, redrawing itself is never done in the handlers booted up in the event loop.

In those handlers, only register the redraw region into the renderer with the SFYResponder::Invalidate function.

At the end of each event loop, the distributer boots up the renderer, which boots up only the drawing handlers for the registered redraw region to be actually displayed on the screen. Then all the redraw processing during the event loop will be done all together.

Reference: Rendering | Register the Redrawing Region | Distributer | Renderer | Tracer | Handler

The drawing handler of MyWindow is updated so that the "Hello Window" string will be drawn depending on the value of "_flagShowHw" flag.

Example 3.22. 

// drawing handler of MyWindow
Void MyWindow::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // MyWindow's local region is filled in light green, 
    // which is set in the constructor with SFYWidget::SetBackgroundColor()

    // display "Hello Window"  when the value of _flagShowHw is "true"
    if (_flagShowHw) {
        graphics->DrawSingleText("Hello Window", GetLocalBound(), COLOR_BLACK);
    }

    return;
}

The following is execution result on BREW simulator.

  1. Press the "1" key in the initial screen. Then MyWindow will be dispalyed.
  2. Press button control 1. Then button control 1 will become disable and button control 2 will become enable.
  3. Press button control 2. Then button control 2 will become disable and button control 1 will become enable.
  4. Press button control 3. Then the "Hello Window" string will be cleared.
  5. Press the CLEAR key in MyWindow. Then MyWindow will be closed.

Figure 3.6. After step 2

After step 2

Figure 3.7. After step 4

After step 4

Reference: Button Control Displaying a Text[SFZTextButtonControl]

3.3.2. Check Box Control

Let's make the check box control(SFZCheckboxControl) as the figure below.

Figure 3.8. Check box control

Check box control

The result handler of the check box control will display its label and current value on BREW Output Window.

The following is the code to declare the check box control and its handler.

Example 3.23. Declare the check box control and its handler

// define the MyWindow class
SFMTYPEDEFRESPONDER(MyWindow)  //  macro to generate the useful types
class MyWindow : public SFZWindow {

    SFMSEALRESPONDER(MyWindow)  //  macro to prohibit the developer from copying this instance

    // macro to specify the inheritance relation from SFYResponder to this class
    SFMRESPONDERINSTANTIATEFOUR(MyWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)

public:

    // since 4-Characters type of small alphabet and symbol are reserved for SophiaFramework UNIVERSE
    // define ('M', 'W', 'N', 'D') of capital alphabets for MyWindow type
    enum CodeEnum {
        CODE_TYPE = four_char_code('M', 'W', 'N', 'D')
    };
    SFMTYPEDEFTYPE(CodeEnum)

private:

    SFZTextButtonControlSmp _button1;
    SFZTextButtonControlSmp _button2;
    SFZTextButtonControlSmp _button3;
    Bool _flagShowHw;

    // *** added code segments are in bold

    // declare the check box control
    SFZCheckboxControlSmp _checkbox1;
    SFZCheckboxControlSmp _checkbox2;

public:

    static MyWindowSmp NewInstance(SFCErrorPtr exception = null);

    // make various controls in MyWindow
    SFCError Make(Void);

protected:

    explicit MyWindow(Void) static_throws;
    virtual ~MyWindow(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;

private:

    SFCError CreateButtons(SFXGridPtr offs);

    // make the check box control
    SFCError CreateCheckBoxes(SFXGridPtr offs);

    XANDLER_DECLARE_BOOLEVENT(OnKey)        // declare the key handler 
    XANDLER_DECLARE_VOIDRESULT(OnButton12)  // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnButton3)   // declare the result handler

    // declare the common result handler of the check box control
    XANDLER_DECLARE_VOIDRESULT(OnCheck)
};

In MyWindow::Make(), check box controls will be created and placed.

Example 3.24. Make the various controls in MyWindow

// make various controls in MyWindow
SFCError MyWindow::Make(Void)
{
    SFXGrid offset(0, 0);
    SFCError error(SFERR_NO_ERROR);

    // set left-top of the drawing region in MyWindow
    offset.Add(X_MARGIN, Y_MARGIN);

    // make the button control in MyWindow
    if ((error = CreateButtons(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    // *** added code segments are in bold

    //  make the check box control in MyWindow
    if ((error = CreateCheckBoxes(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    return error;
}

Next, let's make the check box control.

In this code, properties of the check box control such as a label text or a current value are set.

Example 3.25. Make the check box controls

// make the check box controls
SFCError MyWindow::CreateCheckBoxes(SFXGridPtr offs)
{
    SFXGraphicsPtr graphics = SFXGraphics::GetInstance();
    SInt16Const height = graphics->GetFontHeight() + 4;                   // check box control's height
    SInt16Const width = (GetLocalBound().GetWidth() - 3 * X_MARGIN) / 2;  // check box control's width
    SFXRectangle rect(*offs, width, height);                              // check box control 1's real region 
    SFCError error(SFERR_NO_ERROR);

    // make the check box control 1
    if ((_checkbox1 = SFZCheckboxControl::NewInstance(error)) != null) {

        // set the check box control 1's parent responder to MyWindow
        error = _checkbox1->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

            // register the result handler into the check box control 1
            error = _checkbox1->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnCheck)
            );

            if (error == SFERR_NO_ERROR) {

                // set the check box control 1's label to "Hit"
                error = _checkbox1->SetText("Hit");

                if (error == SFERR_NO_ERROR) {

                    // set the check box control 1's current value to "true"(check box control 1 is checked)
                    _checkbox1->SetCurrentValue(true);

                    // make the check box control 1 left-aligned
                    _checkbox1->SetHorizontalAlign(SFZCheckboxControl::HORIZONTAL_LEFT);

                    // set the check box control 1's real region
                    _checkbox1->SetRealBound(rect);

                    // set the check box control 1's state to "visible" + "active" + "enable" + "unfocus" together 
                    _checkbox1->SetState(true, true, true, false);
                }
            }
        }
    }

    // make the check box control 2
    if ((_checkbox2 = SFZCheckboxControl::NewInstance(error)) != null) {

        // set the check box control 2's parent responder to MyWindow
        error = _checkbox2->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

            // register the result handler into the check box control 2
            error = _checkbox2->RegisterHandler(
              SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
              XANDLER_INTERNAL(OnCheck)
            );

            // set the check box control 2's label to "Run"
            error = _checkbox2->SetText("Run");

            if (error == SFERR_NO_ERROR) {

                // calculate check box control 2's real region
                rect.Offset(X_MARGIN + rect.GetWidth(), 0);

                // make the check box control 2 left-aligned
                _checkbox2->SetHorizontalAlign(SFZCheckboxControl::HORIZONTAL_LEFT);

                // set the check box control 2's real region
                _checkbox2->SetRealBound(rect);

                // set the check box control 2's state to "visible" + "active" + "enable" + "unfocus" together 
                _checkbox2->SetState(true, true, true, false);
            }
        }
    }

    // update the offset
    offs->AddY(rect.GetHeight() + Y_MARGIN);

    return error;
}
[Note] Register the result handler into the check box control

The check box control will receive the result event when the checked state is updated.

To register the result handler into the check box control, use the SFYResponder::RegisterHandler function.

Reference: Result Event[SFEVT_RESPONDER_RESULT] | Handler for the Result Event[XANDLER_DECLARE_VOIDRESULT]

[Note] Operation key

Check box control is operated with the operation key, which is set to the SELECT key by default.

This setting can be changed with the SFYButtonControl::SetOperateKey function.

[Note] Alignment of the check box control

The text label in the check box control will be horizontally and vertically center-aligned in its region by default.

This setting can be changed with the SFZCheckboxControl::SetHorizontalAlign or SFZCheckboxControl::SetVerticalAlign function.

When the real region of the check box control is set by calculating its suitable size with the SFYResponder::GetSuitableBound function, you don't have to mind this alignment setting.

The following is the code to implement the result handler of the check box control, which will be booted up when its checked state is updated.

The result handler will display the label text and current value of the check box control on BREW Output Window.

Example 3.26. Implement the result handler of the check box control

// implement handler of the check box control
XANDLER_IMPLEMENT_VOIDRESULT(MyWindow, OnCheck, invoker, reason, result)
{
    unused(invoker);
    unused(reason);
    unused(result);

    // get the label string
    SFXWideString label1 = _checkbox1->GetText();
    SFXWideString label2 = _checkbox2->GetText();

    // display the label string and the current value on BREW Output Window
    TRACE("%S: %d", label1.GetCString(), _checkbox1->GetCurrentValue());
    TRACE("%S: %d", label2.GetCString(), _checkbox2->GetCurrentValue());

    return;
}
[Note] Current value of the check box control

Current value of the check box control can be obtained with the SFYControl::GetCurrentValue function.

[Caution] Label text of the check box control

The label text of the check box control obtained with the SFZCheckboxControl::GetText function is of the SFXWideString type.

To display the string of the SFXWideString type with the TRACE statement, the S parameter must be used.

Next, let's override the drawing handler "MyWindow::HandleRenderRequest()", which will be booted up when the drawing event[SFEVT_RESPONDER_RENDER] is received.

In the code below, the "Hello Window" string will not be displayed initially.

Example 3.27. 

// window's drawing handler 
Void MyWindow::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // MyWindow's local region is filled in light green, 
    // which is set in the constructor with SFYWidget::SetBackgroundColor()

    // no text will be displayed initially

    return;
}

The following is execution result on BREW simulator.

Figure 3.9. Execution result

Execution result

Figure 3.10. BREW Output Window when the check box control is checked(The label text and its current value of the check box control are outputted.)

BREW Output Window when the check box control is checked(The label text and its current value of the check box control are outputted.)

Reference: Check Box Control[SFZCheckboxControl]

3.3.3. Radio Button Control

Let's make the radio button control[SFZRadiobuttonControl] as the figure below.

Figure 3.11. Radio button control

Radio button control

More than one radio button control are grouped to make each radio button control be checked exclusively.

The following is the code to declare the radio button control and its handler.

Example 3.28. Declare the radio button controls and their handlers

// define the MyWindow class
SFMTYPEDEFRESPONDER(MyWindow)  //  macro to generate the useful types
class MyWindow : public SFZWindow {

    SFMSEALRESPONDER(MyWindow)  //  macro to prohibit the developer from copying this instance

    // macro to specify the inheritance relation from SFYResponder to this class
    SFMRESPONDERINSTANTIATEFOUR(MyWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)

public:

    // since 4-Characters type of small alphabet and symbol are reserved for SophiaFramework UNIVERSE
    // define ('M', 'W', 'N', 'D') of capital alphabets for MyWindow type
    enum CodeEnum {
        CODE_TYPE = four_char_code('M', 'W', 'N', 'D')
    };
    SFMTYPEDEFTYPE(CodeEnum)

private:

    SFZTextButtonControlSmp _button1;
    SFZTextButtonControlSmp _button2;
    SFZTextButtonControlSmp _button3;
    Bool _ifShowHw;
    SFZCheckboxControlSmp _checkbox1;
    SFZCheckboxControlSmp _checkbox2;

    // *** added code segments are in bold

    // declare the radio button controls
    SFZRadiobuttonControlSmp _radio1;
    SFZRadiobuttonControlSmp _radio2;

public:

    static MyWindowSmp NewInstance(SFCErrorPtr exception = null);

    // make various controls in MyWindow 
    SFCError Make(Void);

protected:

    explicit MyWindow(Void) static_throws;
    virtual ~MyWindow(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;

private:

    SFCError CreateButtons(SFXGridPtr offs);
    SFCError CreateCheckBoxes(SFXGridPtr offs);

    // make the radio button controls
    SFCError CreateRadioButtons(SFXGridPtr offs);

    XANDLER_DECLARE_BOOLEVENT(OnKey)        // declare the key handler 
    XANDLER_DECLARE_VOIDRESULT(OnButton12)  // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnButton3)   // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnCheck)     // declare the result handler

    // declare the result handler of the radio button control
    XANDLER_DECLARE_VOIDRESULT(OnRadio)
};

In MyWindow::Make(), radio button controls will be created and placed.

Example 3.29. Make the various controls in MyWindow

// make various controls in MyWindow 
SFCError MyWindow::Make(Void)
{
    SFXGrid offset(0, 0);
    SFCError error(SFERR_NO_ERROR);

    // set the left-top of the content region in MyWindow
    offset.Add(X_MARGIN, Y_MARGIN);

    // make the button controls in MyWindow
    if ((error = CreateButtons(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    // make the check box controls in MyWindow
    if ((error = CreateCheckBoxes(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    // *** added code segments are in bold

    //  make the radio button controls in MyWindow
    if ((error = CreateRadioButtons(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    return error;
}

Next, let's make the radio button control.

In this code, properties of the radio button control such as a label text or a current value are set.

Example 3.30. Make the radio button controls

// make the radio button controls
SFCError MyWindow::CreateRadioButtons(SFXGridPtr offs)
{
    SFXGraphicsPtr graphics = SFXGraphics::GetInstance();
    SInt16Const height = graphics->GetFontHeight() + 4;                  // radio button control's height
    SInt16Const width = (GetLocalBound().GetWidth() - 3 * X_MARGIN) / 2; // radio button control's width
    SFXRectangle rect(*offs, width, height);                             // radio button control 1's real region
    SFCError error(SFERR_NO_ERROR);

    // make the radio button control 1
    if ((_radio1 = SFZRadiobuttonControl::NewInstance(error)) != null) {

        // set the radio button control 1's parent responder to MyWindow
        error = _radio1->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

            // register the result handler into radio button control 1
            error = _radio1->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnRadio)
            );

            if (error == SFERR_NO_ERROR) {

                // set the radio button control 1's label to "Fast"
                error = _radio1->SetText("Fast");

                if (error == SFERR_NO_ERROR) {

                    // set the radio button control 1's current value to "true"(radio button control 1 is checked)
                    _radio1->SetCurrentValue(true);

                    // set the radio button control 1's horizontal alignment to "left-aligned"
                    _radio1->SetHorizontalAlign(SFZRadiobuttonControl::HORIZONTAL_LEFT);

                    // set the radio button control 1's real region
                    _radio1->SetRealBound(rect);

                    // set the radio button control 1's state to "visible" + "active" + "enable" + "unfocus" together 
                    _radio1->SetState(true, true, true, false);
                }
            }
        }
    }

    // make the radio button control 2
    if ((_radio2 = SFZRadiobuttonControl::NewInstance(error)) != null) {

        // set the radio button control 2's parent responder to MyWindow
        error = _radio2->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

           // register the result handler into the radio button control 2
           error = _radio2->RegisterHandler(
               SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
               XANDLER_INTERNAL(OnRadio)
           );

           if (error == SFERR_NO_ERROR) {

               // set the radio button control 2's label to "Slow"
               error = _radio2->SetText("Slow");

               if (error == SFERR_NO_ERROR) {

                   // calculate radio button control 2's real region
                   rect.Offset(X_MARGIN + rect.GetWidth(), 0);

                   // set the radio button control 2's horizontal alignment to "left-aligned"
                   _radio2->SetHorizontalAlign(SFZRadiobuttonControl::HORIZONTAL_LEFT);

                   // set the radio button control 2's real region
                   _radio2->SetRealBound(rect);

                    // set the radio button control 2's state to "visible" + "active" + "enable" + "unfocus" together 
                   _radio2->SetState(true, true, true, false);
               }
           }
        }
    }

    // group radio button control 1 and 2
    _radio1->Group(_radio2);

    // update the offset
    offs->AddY(rect.GetHeight() + Y_MARGIN);

    return error;
}
[Note] Register the result handler into the radio button control

The radio button control will receive the result event when the checked state is changed.

To register the result handler for the result event into the radio button control, use the SFYResponder::RegisterHandler function.

Reference: Result Event[SFEVT_RESPONDER_RESULT] | Handler for the Result Event[XANDLER_DECLARE_VOIDRESULT]

[Note] Operation key

Radio button control is operated with the operation key, which is set to the SELECT key by default.

This setting can be changed with the SFYButtonControl::SetOperateKey function.

[Note] Group radio button controls

Radio button controls are grouped with the SFYRadiobuttonControl::Group function to make each radio button control be checked exclusively.

[Note] Alignment of the radio button control

The text label in the radio button control will be horizontally and vertically center-aligned in the region by default.

This setting can be changed with the SFZRadiobuttonControl::SetHorizontalAlign or SFZRadiobuttonControl::SetVerticalAlign function.

When the real region of the radio button control is set by calculating its suitable size with the SFYResponder::GetSuitableBound function, you don't have to mind this alignment setting.

The following is the code to implement the result handler for the radio button control, which will be booted up when its checked state is changed.

The result handler will display the label text and current value of the radio button control on BREW Output Window.

Example 3.31. Implement the result handler of the radio button control

// implement the result handler of the radio button control
XANDLER_IMPLEMENT_VOIDRESULT(MyWindow, OnRadio, invoker, reason, result)
{
    unused(invoker);
    unused(reason);
    unused(result);

    // get the label string
    SFXWideString label1 = _radio1->GetText();
    SFXWideString label2 = _radio2->GetText();

    // display the label string and the current value on BREW Output Window
    TRACE("%S: %d", label1.GetCString(), _radio1->GetCurrentValue());
    TRACE("%S: %d", label2.GetCString(), _radio2->GetCurrentValue());

    return;
}
[Note] Current value of the radio button control

Current value of the radio button control can be obtained with the SFYControl::GetCurrentValue function.

The below is execution result on BREW simulator.

Figure 3.12. Execution result

Execution result

Figure 3.13.  BREW Output Window when the radio button control is pressed(The label string and its current value of the radio button control is displayed.)

BREW Output Window when the radio button control is pressed(The label string and its current value of the radio button control is displayed.)

Reference: Radio Button Control[SFZRadiobuttonControl]

3.3.4. Combo Box Control

Let's make the combo box control[SFZComboBoxControl] as the figure below.

Figure 3.14. Combo box control

Combo box control
[Note] Scroll items

If all items cannot be displayed in the real region of the parent responder such as MyWindow in this examle, they will be displayed by scrolling up and down. At this time, the scroll bar will be attached automatically.

The following is the code to declare the combo box control and its handler.

Example 3.32. Declare the combo box control and its handler

// define the MyWindow class
SFMTYPEDEFRESPONDER(MyWindow)  //  macro to generate the useful types
class MyWindow : public SFZWindow {

    SFMSEALRESPONDER(MyWindow)  //  macro to prohibit the developer from copying this instance

    // macro to specify the inheritance relation from SFYResponder to this class
    SFMRESPONDERINSTANTIATEFOUR(MyWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
public:

    // since 4-Characters type of small alphabet and symbol are reserved for SophiaFramework UNIVERSE
    // define ('M', 'W', 'N', 'D') of capital alphabets for MyWindow type
    enum CodeEnum {
        CODE_TYPE = four_char_code('M', 'W', 'N', 'D')
    };
    SFMTYPEDEFTYPE(CodeEnum)

private:

    SFZTextButtonControlSmp _button1;
    SFZTextButtonControlSmp _button2;
    SFZTextButtonControlSmp _button3;
    SFZCheckboxControlSmp _checkbox1;
    SFZCheckboxControlSmp _checkbox2;
    SFZRadiobuttonControlSmp _radio1;
    SFZRadiobuttonControlSmp _radio2;
    Bool _ifShowHw;

    // *** added code segments are in bold

    // declare the  combo box control
    SFZComboBoxControlSmp _combobox;

public:

    static MyWindowSmp NewInstance(SFCErrorPtr exception = null);

    // make various controls in MyWindow 
    SFCError Make(Void);

protected:

    explicit MyWindow(Void) static_throws;
    virtual ~MyWindow(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;

private:

    SFCError CreateButtons(SFXGridPtr offs);
    SFCError CreateCheckBoxes(SFXGridPtr offs);
    SFCError CreateRadioButtons(SFXGridPtr offs);

    // make the combo box control
    SFCError CreateComboBox(SFXGridPtr offs);

    XANDLER_DECLARE_BOOLEVENT(OnKey)        // declare the key handler 
    XANDLER_DECLARE_VOIDRESULT(OnButton12)  // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnButton3)   // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnCheck)     // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnRadio)     // declare the result handler

    // declare the result handler of combo box control
    XANDLER_DECLARE_VOIDRESULT(OnComboBox)

    // declare the value handler of combo box control
    XANDLER_DECLARE_VOIDVALUE(OnComboListValue)
};

In MyWindow::Make(), the combo box control will be cereated and placed.

Example 3.33. Make the various controls in MyWindow

// make various controls in MyWindow 
SFCError MyWindow::Make(Void)
{
    SFXGrid offset(0, 0);
    SFCError error(SFERR_NO_ERROR);

    // set the left-top of the content region of MyWindow
    offset.Add(X_MARGIN, Y_MARGIN);

    // make the button controls in MyWindow
    if ((error = CreateButtons(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    // make the check box controls in MyWindow
    if ((error = CreateCheckBoxes(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    // make the radio button controls in MyWindow
    if ((error = CreateRadioButtons(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    // *** added code segments are in bold

    // make the combo box control in MyWindow
    if ((error = CreateComboBox(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    return error;
}

Next, let's make the combo box control.

In this code, properties of the combo box control such as an item are set.

Example 3.34. Make the combo box control

// make the combo box control
SFCError MyWindow::CreateComboBox(SFXGridPtr offs)
{
    SFXGraphicsPtr graphics = SFXGraphics::GetInstance();
    SInt16Const height = graphics->GetFontHeight() + 4;              // combo box control's height
    SInt16Const width = (GetLocalBound().GetWidth() - 2 * X_MARGIN); // combo box control's width
    SFXRectangle rect(*offs, width, height);                         // combo box control's real region 
    SFCError error(SFERR_NO_ERROR);

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

        // set the combo box control's parent responder to MyWindow
        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(OnComboBox)
            );

            if (error == SFERR_NO_ERROR) {

                // register the value handler into the flex list box control
                error = _combobox->GetListBoxControl()->RegisterHandler(
                    SFXEventRange(SFEVT_RESPONDER_VALUE, SFEVT_RESPONDER_VALUE, SFP16_VALUE_CURRENT, SFP16_VALUE_CURRENT),
                    XANDLER_INTERNAL(OnComboListValue)
                );

                if (error == SFERR_NO_ERROR) {

                    // set values for the combo box control's item
                    SFXWideString item[] = {"First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Eighth", "Ninth", "Tenth"};

                    // append array of the items on combo box control together
                    error = _combobox->InsertLast(item, lengthof(item));

                    if (error == SFERR_NO_ERROR) {

                        // set the combo box control's real region
                        _combobox->SetRealBound(rect);

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


    // update the offset
    offs->AddY(rect.GetHeight() + Y_MARGIN);
    return error;
}
[Note] Register the result handler into the combo box control and the value handler into the flex list box control

The combo box control will receive the result event when the item is selected newly. And the flex list box control which the combo box control contains internally will receive the value event when focus is moved among the items.

With the SFYResponder::RegisterHandler function, you can register the result handler for the result event into the combo box control and the value handler for the value event into the flex list box control.

Reference: Result Event[SFEVT_RESPONDER_RESULT] | Value Event[SFEVT_RESPONDER_VALUE] | Handler for the Result Event[XANDLER_DECLARE_VOIDRESULT] | Handler for the Value Event[XANDLER_DECLARE_VOIDVALUD]

[Note] Operation key

Combo box control is operated with the operation key, which is set to the SELECT key by default.

This setting can be changed with the SFYButtonControl::SetOperateKey function.

The following is the code to implement the result handler of the combo box control and the value handler of the flex list box control which will be booted up when the item is selected newly and the focus is moved among items respectively.

The result handler and the value handler will display the text and number of the selected item from the flex list box control on BREW Output Window respectively.

Example 3.35. Implement the result handler of the combo box control

// implement the result handler of the combo box control
XANDLER_IMPLEMENT_VOIDRESULT(MyWindow, OnComboBox, invoker, reason, result)
{
    unused(invoker);
    unused(reason);

    if (reason == SFP16_RESULT_OK) {

        // get the selected item's string
        // result: selected item number
        SFXWideString string(_combobox->GetItemText(result));

        // display the selected item's number and string on BREW Output Window
        TRACE("'CB%d: %S' is selected.", result, string.GetCString());
    }
    return;
}

// implement the value handler of the flex list box control
XANDLER_IMPLEMENT_VOIDVALUE(MyWindow, OnComboListValue, invoker, reason, value)
{
    unused(invoker);
    unused(reason);

    // display the focused item's number on BREW Output Window
    // value: focused item number
    TRACE("'CB%d'", value);

    return;
}

The following is execution result on BREW simulator.

Figure 3.15. Execution result

Execution result

Figure 3.16.  BREW Output Window when the item of the combo box control is newly selected(The selected item number and its string are displayed.)

BREW Output Window when the item of the combo box control is newly selected(The selected item number and its string are displayed.)

Reference: Combo Box Control[SFZComboBoxControl]

3.3.5. Text Label Control and Edit Box Control

Let's make the text label control(SFZSingleTextLabelControl) and an edit box control(SFZSingleEditBoxControl) as the figure below.

Figure 3.17. Text label control and edit box control

Text label control and edit box control

This code will authentificate inputted password in the edit box control by simply comparing its string with true password.

The following is the code to declare the text label control, the edit box control, and their handlers.

Example 3.36. Declare the text label control, the edit box control, and their handlers

// define the MyWindow class
SFMTYPEDEFRESPONDER(MyWindow)  //  macro to generate the useful types
class MyWindow : public SFZWindow {

    SFMSEALRESPONDER(MyWindow)  //  macro to prohibit the developer from copying this instance

    // macro to specify the inheritance relation from SFYResponder to this class
    SFMRESPONDERINSTANTIATEFOUR(MyWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
public:

    // since 4-Characters type of small alphabet and symbol are reserved for SophiaFramework UNIVERSE
    // define ('M', 'W', 'N', 'D') of capital alphabets for MyWindow type
    enum CodeEnum {
        CODE_TYPE = four_char_code('M', 'W', 'N', 'D')
    };
    SFMTYPEDEFTYPE(CodeEnum)

private:

    SFZTextButtonControlSmp _button1;
    SFZTextButtonControlSmp _button2;
    SFZTextButtonControlSmp _button3;
    SFZCheckboxControlSmp _checkbox1;
    SFZCheckboxControlSmp _checkbox2;
    SFZRadiobuttonControlSmp _radio1;
    SFZRadiobuttonControlSmp _radio2;
    Bool _ifShowHw;
    SFZComboBoxControlSmp _combobox;

    // *** added code segments are in bold

    // declare the text label control and the edit box control
    SFZSingleTextLabelControlSmp _singleTextLabel;
    SFZSingleEditBoxControlSmp _singleEditBox;

public:

    static MyWindowSmp NewInstance(SFCErrorPtr exception = null);

    // make various controls in MyWindow
    SFCError Make(Void);

protected:

    explicit MyWindow(Void) static_throws;
    virtual ~MyWindow(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;
private:

    SFCError CreateButtons(SFXGridPtr offs);
    SFCError CreateCheckBoxes(SFXGridPtr offs);
    SFCError CreateRadioButtons(SFXGridPtr offs);
    SFCError CreateComboBox(SFXGridPtr offs);

    // make the text label control and edit box control
    SFCError CreatePassLine(SFXGridPtr offs);

    XANDLER_DECLARE_BOOLEVENT(OnKey)             // declare the key handler 
    XANDLER_DECLARE_VOIDRESULT(OnButton12)       // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnButton3)        // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnCheck)          // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnRadio)          // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnComboBox)       // declare the result handler 
    XANDLER_DECLARE_VOIDVALUE(OnComboListValue)  // declare the value handler

    // declare the result handler of the edit box control
    XANDLER_DECLARE_VOIDRESULT(OnSingleEditBox)
};

In MyWindow::Make(), the text label control and the edit box control will be created and placed.

Example 3.37. Make the various controls in MyWindow

// make various controls in MyWindow 
SFCError MyWindow::Make(Void)
{
    SFCError error;

    SFXGrid offset(0, 0);

    // set the left-top of the content region of MyWindow
    offset.Add(X_MARGIN, Y_MARGIN);

    // make the button controls in MyWindow
    if ((error = CreateButtons(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    // make the check box controls in MyWindow
    if ((error = CreateCheckBoxes(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    //  make the radio button controls in MyWindow
    if ((error = CreateRadioButtons(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    // make the combo box control in MyWindow
    if ((error = CreateComboBox(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    // *** added code segments are in bold

    // make the text label control and edit box control in MyWindow
    if ((error = CreatePassLine(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    return error;
}

The following is the code to make the text label control and the edit box control.

In this code below, maximum input length of the edit box control is set to 10 characters, inputted string will not be displayed in it but the string like "**********" will be displayed, and the text label control will not be focused.

Example 3.38. Make the text label control and the edit box control

// make the text label control and edit box control
SFCError MyWindow::CreatePassLine(SFXGridPtr offs)
{
    SFCError error;
    SFXRectangle rect;

    // make the text label control
    if ((_singleTextLabel = SFZSingleTextLabelControl::NewInstance(&error)) != null) {

        // set the text label control's parent responder to MyWindow
        error = _singleTextLabel->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

            // set the text label control's label to "PW:"
            error = _singleTextLabel->SetText("PW:");

            if (error == SFERR_NO_ERROR) {

                // calculate the suitable real region for text label control
                rect.Set(*offs, _singleTextLabel->GetSuitableBound().GetSize());

                // set the text label control's real region
                _singleTextLabel->SetRealBound(rect);

                // set the text label control's state to "visible" + "active" + "disable" + "unfocus" together 
                _singleTextLabel->SetState(true, true, false, false);
            }
        }
    }

    // make the edit box control
    if ((_singleEditBox = SFZSingleEditBoxControl::NewInstance(&error)) != null) {

        // set the edit box control's parent responder to MyWindow
        error = _singleEditBox->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

            // register the result handler into the edit box control
            error = _singleEditBox->RegisterHandler(
                SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnSingleEditBox)
            );

            if (error == SFERR_NO_ERROR) {

                // set the edit box control's password mode to "true"
                error = _singleEditBox->SetPasswordMode(true);

                if (error == SFERR_NO_ERROR) {

                    // set the edit box control's maximum input length to 10 characters
                    error = _singleEditBox->SetMaximumLength(10);

                    if (error == SFERR_NO_ERROR) {

                        // only aphabet and number can be inputted
                        _singleEditBox->SetInputMode(AEE_TM_LETTERS | AEE_TM_NUMBERS);

                        // set the edit box control's horizontal alignment to "left-aligned"
                        _singleEditBox->SetHorizontalAlign(SFZSingleEditBoxControl::HORIZONTAL_LEFT);

                        // calculate the edit box control's real region
                        rect.Offset(rect.GetWidth(), 0);
                        rect.SetRight(GetLocalBound().GetWidth() - X_MARGIN);

                        // set the edit box control's real region
                        _singleEditBox->SetRealBound(rect);

                        // set the edit box control's state to "visible" + "active" + "enable" + "unfocus" together 
                        _singleEditBox->SetState(true, true, true, false);
                    }
                }
            }
        }
    }


    // update the offset
    offs->AddY(rect.GetHeight() + Y_MARGIN);
    return error;
}
[Note] Register the resulthandler into the edit box control

The edit box control will receive the result event when the inputted content is changed.

You can register the result handler for the result event into the edit box control with the SFYResponder::RegisterHandler function.

Reference: Result Event[SFEVT_RESPONDER_RESULT] | Handler for the Result Event[XANDLER_DECLARE_VOIDRESULT]

[Note] Operation key

Edit box control control is operated with the operation key, which is set to the SELECT key by default.

This setting can be changed with the SFYBoxControl::SetOperateKey function.

The following is the code to implement the result handler, which will be booted up when the inputted contents in the edit box control is changed.

The result handler will display password authentification result on BREW Output Window.

Example 3.39. Implement the result handler of the edit box control

// implement the result handler of the edit box control
XANDLER_IMPLEMENT_VOIDRESULT(MyWindow, OnSingleEditBox, invoker, reason, result)
{
    unused(invoker);
    unused(reason);
    unused(result);

    // compare the string with true password
    if (_singleEditBox->GetText().Compare("pass") == 0) {
        TRACE("password: authenticated!");
    } else {
        TRACE("password: can't be authenticated...");
    }

    return;
}

The following is execution result on BREW simulator.

Figure 3.18. Execution result

Execution result

Figure 3.19. Text Input Screen

Text Input Screen

Figure 3.20. BREW Output Window when password is inputted(authentification result is displayed)

BREW Output Window when password is inputted(authentification result is displayed)

Reference: Label Control Displaying Single Uneditable Text[SFZSingleTextLabelControl] | Box ControlDisplaying Single Editable Text[SFZSingleEditBoxControl]

3.3.6. List Box Control

Let's make the list box control(SFZListBoxControl) as the figure below.

Figure 3.21. List box control

List box control

The content of the list box control is synchronized with that of the combo box control when the item is selected.

[Note] Two kinds of the list box controls

There are two types of the list box controls: SFZListBoxControl and SFZFlexListBoxControl.

Here the former is used, and the latter is used inside the combo box control.

Both are the controls to select an item from the list and have many common APIs, but the latter is more advanced than the former.

For more details, see SFZFlexListBoxControl.

The following is the code to declare the list box control and its handler.

Example 3.40. Declare the list box control and its handler

// define the MyWindow class
SFMTYPEDEFRESPONDER(MyWindow)  //  macro to generate the useful types
class MyWindow : public SFZWindow {

    SFMSEALRESPONDER(MyWindow)  //  macro to prohibit the developer from copying this instance

    // macro to specify the inheritance relation from SFYResponder to this class
    SFMRESPONDERINSTANTIATEFOUR(MyWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)

public:

    // since 4-Characters type of small alphabet and symbol are reserved for SophiaFramework UNIVERSE
    // define ('M', 'W', 'N', 'D') of capital alphabets for MyWindow type
    enum CodeEnum {
        CODE_TYPE = four_char_code('M', 'W', 'N', 'D')
    };
    SFMTYPEDEFTYPE(CodeEnum)

private:

    SFZTextButtonControlSmp _button1;
    SFZTextButtonControlSmp _button2;
    SFZTextButtonControlSmp _button3;
    SFZCheckboxControlSmp _checkbox1;
    SFZCheckboxControlSmp _checkbox2;
    SFZRadiobuttonControlSmp _radio1;
    SFZRadiobuttonControlSmp _radio2;
    Bool _ifShowHw;
    SFZComboBoxControlSmp _combobox;
    SFZSingleTextLabelControlSmp _singleTextLabel;
    SFZSingleEditBoxControlSmp _singleEditBox;

    // *** added code segments are in bold

    // declare the list box control
    SFZListBoxControlSmp _listbox;

public:

    static MyWindowSmp NewInstance(SFCErrorPtr exception = null);

    // make various controls in MyWindow 
    SFCError Make(Void);

protected:

    explicit MyWindow(Void) static_throws;
    virtual ~MyWindow(Void);
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const;

private:

    SFCError CreateButtons(SFXGridPtr offs);
    SFCError CreateCheckBoxes(SFXGridPtr offs);
    SFCError CreateRadioButtons(SFXGridPtr offs);
    SFCError CreateComboBox(SFXGridPtr offs);
    SFCError CreatePassLine(SFXGridPtr offs);

    // make list box control
    SFCError CreateListBox(SFXGridPtr offs);

    XANDLER_DECLARE_BOOLEVENT(OnKey)             // declare the key handler 
    XANDLER_DECLARE_VOIDRESULT(OnButton12)       // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnButton3)        // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnCheck)          // declare the result handler
    XANDLER_DECLARE_VOIDRESULT(OnRadio)          // declare the result handler 
    XANDLER_DECLARE_VOIDRESULT(OnComboBox)       // declare the result handler
    XANDLER_DECLARE_VOIDVALUE(OnComboListValue)  // declare the value handler
    XANDLER_DECLARE_VOIDRESULT(OnSingleEditBox)  // declare the result handler

    // declare the result handler of the list box control
    XANDLER_DECLARE_VOIDRESULT(OnListBox)

    // declare the value handler of the list box control
    XANDLER_DECLARE_VOIDVALUE(OnListValue)
};

In MyWindow::Make(), the list box control will be created and placed.

Example 3.41. Create and place various controls in MyWindow

// make various controls in MyWindow
SFCError MyWindow::Make(Void)
{
    SFCError error;

    SFXGrid offset(0, 0);

    // set the left-top of the content region of MyWindow
    offset.Add(X_MARGIN, Y_MARGIN);

    // make the button control in MyWindow
    if ((error = CreateButtons(&offset)) != SFERR_NO_ERROR) {
        TRACE("button error");
        return error;
    }

    // make the check box control in MyWindow
    if ((error = CreateCheckBoxes(&offset)) != SFERR_NO_ERROR) {
        TRACE("check box error");
        return error;
    }

    // make the radio button control in MyWindow
    if ((error = CreateRadioButtons(&offset)) != SFERR_NO_ERROR) {
        TRACE("radio button error");
        return error;
    }

    // make the combo box control in MyWindow
    if ((error = CreateComboBox(&offset)) != SFERR_NO_ERROR) {
        TRACE("combo error");
        return error;
    }

    // make the text label control and edit box control in MyWindow
    if ((error = CreatePassLine(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    // *** added code segments are in bold

    //  make the list box control in MyWindow
    if ((error = CreateListBox(&offset)) != SFERR_NO_ERROR) {
        return error;
    }

    return error;
}

Next, let's make the list box control.

In this code, properties of the list box control such as an item are set.

Example 3.42. Create and place the list box control

// make the list box control
SFCError MyWindow::CreateListBox(SFXGridPtr offs)
{
    SFXEventRange::AtomRecConst range[] = {                          // event range for the list box control's handler
        {SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END},
        {SFEVT_RESPONDER_VALUE, SFEVT_RESPONDER_VALUE, SFP16_VALUE_CURRENT, SFP16_VALUE_CURRENT}
    };
    SFYHandler::RuleRec rule[lengthof(range)];                       // handler rule
    SInt16Const width = (GetLocalBound().GetWidth() - 2 * X_MARGIN); // list box control's width
    SFXRectangle rect(*offs, width, 0);                              // list box control's real region
    SFCError error(SFERR_NO_ERROR);

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

        // set the list box control's parent responder to MyWindow
        error = _listbox->SetParent(GetThis());

        if (error == SFERR_NO_ERROR) {

            // set the handler rule for the list box control
            rule[0].spp = XANDLER_FUNCTION(OnListBox);               // set result handler of the list box control
            rule[0].reference = this;                                // set pointer to MyWindow(contains OnListBox)
            rule[1].spp = XANDLER_FUNCTION(OnListValue);             // set value handler of the list box control
            rule[1].reference = this;                                // set pointer to MyWindow(contains OnListValue)

            // register all handlers for the list box control together
            error = _listbox->RegisterHandler(atomic_cast(range), rule, lengthof(range));

            if (error == SFERR_NO_ERROR) {

                // items of the list box control
                SFXWideString item[] = {"First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Eighth", "Ninth", "Tenth"};

                for (SInt16 i = 0; i < lengthof(item); ++i) {

                    // append item on the list box control
                    error = _listbox->InsertLast(item[i]);

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

                    // set the list box control's move-item-up key to LEFT key
                    _listbox->SetUpKey(AVK_LEFT);

                    // set the list box control's move-item-down key to RIGHT key
                    _listbox->SetDownKey(AVK_RIGHT);

                    // set real region's height to 80
                    rect.SetHeight(80);

                    // set the list box control's real region
                    // real region's height is adjusted with GetSuitableBound()
                    _listbox->SetRealBound(_listbox->GetSuitableBound(rect).SetWidth(rect.GetWidth()));

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

    // update the offset
    offs->AddY(rect.GetHeight() + Y_MARGIN);
    return error;
}
[Note] Register the result handler and the value handler into the list box control

The list box control will receive the result event when the item is selected, and it will also receive the value event when the number of the selected item is changed.

You can register the result handler for the result event and the value handler for the value event into the list box control with the SFYResponder::RegisterHandler function.

In the above example, effective method to register more than one event handler together at the same time is adopted.

Reference: Result Event[SFEVT_RESPONDER_RESULT] | Value Event[SFEVT_RESPONDER_VALUE] | Handler for the Result Event[XANDLER_DECLARE_VOIDRESULT] | Handler for the Value Event[XANDLER_DECLARE_VOIDVALUD]

[Note] Operation key

List box control control is operated with the operation key, which is set to the SELECT key by default.

This setting can be changed with the SFYBoxControl::SetOperateKey function.

[Note] Scroll items

If all items cannot be displayed in the real region of the list box control, they can be displayed by scrolling up and down. At this time, the scroll bar will be attached automatically.

[Caution] Collision of the move-focus key and the move-item key

The focus is moved among items of the list box control with the UP key and the DOWN key by default.

On the other hand, default keys to move the focus among the "enable" controls in MyWindow are the UP key and the DOWN key too.

Since default settings of the move-focus key of MyWindow and the move-item key of the list box control collide, the focus cannot be moved from the list box control to other contols in MyWindow with the UP key and the DOWN key as they are.

It is necessary to change the default settings of the move-focus key of MyWindow or the move-item key of the list box control.

Therefore, the LEFT / RIGHT key is set to the key for moving the focus among items of the list box control with the SFZListBoxControl::SetUpKey / SFZListBoxControl::SetDownKey function in the above example.

Reference: SFZListBoxControl::SetUpKey | SFZListBoxControl::SetDownKey | SFYContainer::ScrollUp | SFYContainer::ScrollDown | SFYContainer::SetScrollUpKey | SFYContainer::SetScrollDownKey

Let's implement each handler as follows:

  1. Implementation of the result handler of the list box control: [1]Display the selected item's number and string on BREW Output Window. [2]Synchronize the combo box control with the list box control.
  2. Implementation of the value handler of the list box control: Display the focused item's number on BREW Output Window.
  3. Update of implementation of the result handler of the combo box control: Synchronize the list box control with the combo box control.

Example 3.43. Implement the handlers of the list box control and the combo box control

// implement the result handler of the list box control
XANDLER_IMPLEMENT_VOIDRESULT(MyWindow, OnListBox, invoker, reason, result)
{
    unused(invoker);
    unused(reason);

    if (reason == SFP16_RESULT_OK) {

        // get the string of the selected item
        // result: number of the selected item
        SFXWideString string(_listbox->GetItemText(result));

        // display the selected item's number and string on BREW Output Window
        TRACE("'LB%d: %S' is selected.", result, string.GetCString());

        // synchronize the list box control with the combo box control
        _combobox->SetCurrentValue(result);
    }
    return;
}

// implement the value handler of the list box control
XANDLER_IMPLEMENT_VOIDVALUE(MyWindow, OnListValue, invoker, reason, value)
{
    unused(invoker);
    unused(reason);

    // display the focused item's number on BREW Output Window
    // value: focused item number
    TRACE("'LB%d'", value);

    return;
}

// implement the result handler of the combo box control
XANDLER_IMPLEMENT_VOIDRESULT(MyWindow, OnComboBox, invoker, reason, result)
{
    unused(invoker);
    unused(reason);

    if (reason == SFP16_RESULT_OK) {

        // get the string of the selected item
        // result: number of the selected item
        SFXWideString string(_combobox->GetItemText(result));

        // display the selected item's number and string on BREW Output Window
        TRACE("'CB%d: %S' is selected.", result, string.GetCString());

        // *** added code segments are in bold

        // synchronize the list box control with the combo box control
        _listbox->SetCurrentValue(result);
    }
    return;
}

The following is execution result on BREW simulator.

Figure 3.22. Execution result

Execution result

Figure 3.23. BREW Output Window when the item of the list box control is selected

BREW Output Window when the item of the list box control is selected

Reference: List Box Control[SFZListBoxControl]