SophiaFramework UNIVERSE 5.3 |
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.
Let's make three text button controls(SFZTextButtonControl) as the figure below.
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) };
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. |
Declaration and implementation of the result handler | |
---|---|
The result handler is declared / implemented with the XANDLER_DECLARE_VOIDRESULT / XANDLER_IMPLEMENT_VOIDRESULT macro. |
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; }
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] |
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. |
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.
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. |
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; }
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.
Reference: Button Control Displaying a Text[SFZTextButtonControl]
Let's make the check box control(SFZCheckboxControl) as the figure below.
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; }
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] |
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. |
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; }
Current value of the check box control | |
---|---|
Current value of the check box control can be obtained with the SFYControl::GetCurrentValue function. |
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.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.)
Reference: Check Box Control[SFZCheckboxControl]
Let's make the radio button control[SFZRadiobuttonControl] as the figure below.
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; }
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] |
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. |
Group radio button controls | |
---|---|
Radio button controls are grouped with the SFYRadiobuttonControl::Group function to make each radio button control be checked exclusively. |
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; }
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.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.)
Reference: Radio Button Control[SFZRadiobuttonControl]
Let's make the combo box control[SFZComboBoxControl] as the figure below.
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; }
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] |
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.16. 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]
Let's make the text label control(SFZSingleTextLabelControl) and an edit box control(SFZSingleEditBoxControl) as the figure below.
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; }
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] |
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.
Reference: Label Control Displaying Single Uneditable Text[SFZSingleTextLabelControl] | Box ControlDisplaying Single Editable Text[SFZSingleEditBoxControl]
Let's make the list box control(SFZListBoxControl) as the figure below.
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; }
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] |
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. |
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. |
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:
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.
Reference: List Box Control[SFZListBoxControl]
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |