SophiaFramework UNIVERSE 5.3 |
Event(SFXEvent) consists of an event type and 2 parameters(P16 parameter and P32 parameter).
There are three types of events as follows:
User-defined event is an event in the range from SFEVT_USER_CLASS_BEGIN(0x8000) to SFEVT_USER_CLASS_END(0xFFFE), which you can define and use as your own event.
In this section, how to use the user-defined event will be described.
Reference: Event | SFCEventEnum
Let's apply color scheme selected by the text menu to the SoftKey control, the tab control, and the frame of the window.
Color scheme of the responder can be changed by distributing the user-defined event with color scheme information to the responder.
First, let's define the user-defined event(hereafter called the SFEVT_USER_COLOR event) to distribute the custom color structure.
Concretely, we will define the SFEVT_USER_COLOR event value and the SFEVT_USER_COLOR event handler macros.
Example 3.72. Define the SFEVT_USER_COLOR event value
// SFEVT_USER: starting value of user-defined event
#define SFEVT_USER_COLOR (SFEVT_USER + 0x0001)
#define SFP16_USER_COLOR 0
Example 3.73. Define the SFEVT_USER_COLOR event handler macros
// declaration macro #define XANDLER_DECLARE_VOIDUSERCOLOR(FUNCTION) \ static Bool XANDLER_FUNCTION(FUNCTION)(SFYResponderPtr invoker, SFXEventConstRef event, VoidPtr reference); \ Void FUNCTION(SFYResponderPtr invoker, UInt16 reason, UserColorPtr color); // implementation macro // * pointer to the UserColor structure passed as the P32 parameter #define XANDLER_IMPLEMENT_VOIDUSERCOLOR(TYPE, FUNCTION, INVOKER, REASON, COLOR) \ Bool XANDLER_FUNCTION(TYPE::FUNCTION)(SFYResponderPtr invoker, SFXEventConstRef event, VoidPtr reference) \ { \ static_cast<TYPE*>(reference)->FUNCTION(invoker, event.GetP16(), reinterpret_cast<UserColorPtr>(event.GetP32())); \ return true; \ } \ \ Void TYPE::FUNCTION(SFYResponderPtr INVOKER, UInt16 REASON, UserColorPtr COLOR)
This handler is declared, registered, and implemented similarly to the responder-defined event as follows:
// declare the handler for the SFEVT_USER_COLOR event
XANDLER_DECLARE_VOIDUSERCOLOR(OnColor)
// register handler for the SFEVT_USER_COLOR event
RegisterHandler(
SFXEventRange(SFEVT_USER_COLOR, SFEVT_USER_COLOR, SFP16_USER_COLOR, SFP16_USER_COLOR),
XANDLER_INTERNAL(OnColor)
);
// implement handler for the SFEVT_USER_COLOR event XANDLER_IMPLEMENT_VOIDUSERCOLOR(helloworld, OnColor, invoker, reason, color) { // ... return; }
However, the SFEVT_USER_COLOR event will not be distributed to target responders as it is.
We have to register its dispatching rule into the tracer of the distributer(SFYDistributer).
Registration of the dispatching rule into the distributer will be done in the constructor of the application class(in this case, the helloworld application class) as follows:
Example 3.74. Register the dispatching rule into the tracer of the distributer
// constructor helloworld::helloworld(Void) static_throws { if (static_try()) { // *** added code segments are in bold SFYDistributerPtr distributer; if ((distributer = GetDistributer()) != null) { // register the dispatching rule on user-defined event into the tracer of the distributer // * distribute to all visible responders from background to foreground with the overloading condition flag as "true" static_throw(distributer->RegisterTracer( SFXEventRange(SFEVT_USER_COLOR, SFEVT_USER_COLOR, SFP16_USER_COLOR, SFP16_USER_COLOR), SFYTracer::ORDER_BACKWARD, SFYTracer::STATE_VISIBLE, true )); if (static_try()) { //...(omitted)... } } else { static_throw(SFERR_FAILED); } } }
Next, let's update the result handler of the text menu to distribute the SFEVT_USER_COLOR event to responders actually.
Example 3.75. Distribute the SFEVT_USER_COLOR event
// result handler of the text menu XANDLER_IMPLEMENT_VOIDRESULT(helloworld, OnMenuResult, invoker, reason, result) { // ...(omitted)... switch (reason) { case SFP16_RESULT_OK: TRACE("'%S' is selected", _textMenu->GetItemText(static_cast<SInt16>(result)).GetCString()); switch (result) { case 0: case 1: case 2: case 3: { SetMenuColors((color[result])); MakeColorDialog(_textMenu->GetItemText(result), (color[result])); // *** added code segments are in bold // get the root SFYResponderSmp root; if ((root = GetRoot()) != null) { // distribute the color scheme event at the root // * give the pointer to the UserColor class as the P32 parameter error = root->Distribute( SFXEvent(SFEVT_USER_COLOR, SFP16_USER_COLOR, reinterpret_cast<UInt32>(&color[result])) ); } break; } } break; // ...(omitted)... } return; }
Distribute function | |
---|---|
To distribute an event to child responders , use Type 1 of the SFYResponder::Distribute function. In this case, it is necessary to register its dispatching rule into the tracer. The SFYResponder::InvokeBackward / SFYResponder::InvokeForward function is used to send an event to a specific responder in the callback type. In this case, the event will not be distributed to child responders. |
Reference: Handler | Handler List | Callback Type | Distribute Type | Distributer | Tracer Event | SFYResponder::InvokeForward | SFYResponder::InvokeBackward | SFYResponder::Distribute
In the end, the SFEVT_USER_COLOR event will be received by responders such as the SoftKey control, the frame of the window, or the tab control by registering its handlers into those responders.
Example 3.76. Register color scheme handlers
// define the helloworld class SFMTYPEDEFCLASS(helloworld) // macro to generate the useful types class helloworld : public SFYApplication { SFMSEALCOPY(helloworld) // macro to prohibit the developer from copying this instance private: MyWindowSmp _myWindow; ItsWindowSmp _itsWindow; SFZTextMenuSmp _textMenu; TabWindowSmp _tabWindow; SFZSoftKeyControlSmp _softkey; SFZTitlePlainFrameSmp _windowFrame; SFZTitleBevelFrameSmp _dialogFrame; public: static SFCInvokerPtr Factory(Void); private: // ...(omitted)... // *** added code segments are in bold // color scheme handler of the SoftKey control XANDLER_DECLARE_VOIDUSERCOLOR(OnSoftColor) // color scheme handler of the window frame XANDLER_DECLARE_VOIDUSERCOLOR(OnWindowFrameColor) }; // define the TabWindow class SFMTYPEDEFRESPONDER(TabWindow) // macro to generate the useful types class TabWindow : public SFZWindow { SFMSEALRESPONDER(TabWindow) // macro to prohibit the developer from copying this instance // macro to specify the inheritance relation from SFYResponder to this class SFMRESPONDERINSTANTIATEFOUR(TabWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder) public: enum CodeEnum { CODE_TYPE = four_char_code('T', 'A', 'B', 'W') }; SFMTYPEDEFTYPE(CodeEnum) private: SFZTabControlSmp _tab; public: static TabWindowSmp NewInstance(SFCErrorPtr exception = null); SFCError Make(); protected: explicit TabWindow(Void) static_throws; virtual ~TabWindow(Void); private: XANDLER_DECLARE_BOOLEVENT(OnKey) // declare the key handler // color scheme handler of tab control XANDLER_DECLARE_VOIDUSERCOLOR(OnTabColor) }; // constructor helloworld::helloworld(Void) static_throws { if (static_try()) { SFYDistributerPtr distributer; if ((distributer = GetDistributer()) != null) { // set the dispatching rule of the user-defined event into the distributer's tracer // * distribute this event to the visible responders from background to foreground (overloading condition: true) static_throw(distributer->RegisterTracer( SFXEventRange(SFEVT_USER_COLOR, SFEVT_USER_COLOR, SFP16_USER_COLOR, SFP16_USER_COLOR), SFYTracer::ORDER_BACKWARD, SFYTracer::STATE_VISIBLE, true )); if (static_try()) { // ...(omitted)... if ((_softkey = SFZSoftKeyControl::NewInstance()) != null) { static_throw(_softkey->SetParent(GetThis())); if (static_try()) { // register the color scheme handler into the SoftKey control static_throw(_softkey->RegisterHandler( SFXEventRange(SFEVT_USER_COLOR, SFEVT_USER_COLOR, SFP16_USER_COLOR, SFP16_USER_COLOR), XANDLER_INTERNAL(OnSoftColor) )); if (static_try()) { // ...(omitted)... } } } } else { static_throw(SFERR_NO_MEMORY); } } } else { static_throw(SFERR_FAILED); } } } // make the window frame SFCError helloworld::MakeWindowFrame(SFXWideStringConstRef title) { SFCError error(SFERR_NO_ERROR); if ((_windowFrame = SFZTitlePlainFrame::NewInstance(&error)) != null) { // register the color scheme handler into the window frame error = _windowFrame->RegisterHandler( SFXEventRange(SFEVT_USER_COLOR, SFEVT_USER_COLOR, SFP16_USER_COLOR, SFP16_USER_COLOR), XANDLER_INTERNAL(OnWindowFrameColor) ); if (error == SFERR_NO_ERROR) { // ...(omitted)... } } return error; } // make the child responder(tab control) of TabWindow SFCError TabWindow::Make() { MyWindowSmp myWindow; CustomContainerSmp customContainer; SFCError error(SFERR_NO_ERROR); if ((_tab = SFZTabControl::NewInstance(&error)) != null) { error = _tab->SetParent(GetThis()); if (error == SFERR_NO_ERROR) { // register the color scheme handler into the tab control error = _tab->RegisterHandler( SFXEventRange(SFEVT_USER_COLOR, SFEVT_USER_COLOR, SFP16_USER_COLOR, SFP16_USER_COLOR), XANDLER_INTERNAL(OnTabColor) ); if (error == SFERR_NO_ERROR) { // ...(omitted)... } } } return error; }
At last, let's implement the color scheme handler to update the color scheme of dialog frame.
Example 3.77. Implement the color scheme handler
// color scheme handler of the SoftKey control XANDLER_IMPLEMENT_VOIDUSERCOLOR(helloworld, OnSoftColor, invoker, reason, color) { unused(invoker); unused(reason); // set the SoftKey control's background color _softkey->SetBackgroundColor(color->itemBack); // set the SoftKey control's label color // * if nothing specified, SoftKey menu refers to the color of the "0" key // * since the color key of the SoftKey menu is not changed // * all SoftKey menus refer to the color of the "0" key _softkey->RegisterFrameColor(0, color->dark); _softkey->RegisterBackColor(0, color->titleBack); _softkey->RegisterForeColor(0, color->titleFore); return; } // color scheme handler of the window frame XANDLER_IMPLEMENT_VOIDUSERCOLOR(helloworld, OnWindowFrameColor, invoker, reason, color) { unused(invoker); unused(reason); // set the color for the frame header _windowFrame->SetHeaderColor(color->titleBack); // set the color for the frame title _windowFrame->SetTextColor(color->titleFore); return; } // color scheme handler of the tab control XANDLER_IMPLEMENT_VOIDUSERCOLOR(TabWindow, OnTabColor, invoker, reason, color) { unused(invoker); unused(reason); // set the tab control's background color _tab->SetBackgroundColor(color->base); // set the color for the tab control's hint bevel _tab->SetHintBevelColor(SFXBevelColor(color->light, color->base, color->dark)); // set the color for the tab control's bevel _tab->SetTabBevelColor(SFXBevelColor(color->light, color->base, color->dark)); // get all tab pages and set their tab page's titlestring color for (SInt16 i = 0; i < _tab->GetPageCount(); ++i) { SFZTabPageSmp page = _tab->GetPage(i); page->SetTextColor(color->selFore); } return; } // make the dialog SFCError helloworld::MakeColorDialog(SFXWideStringConstRef title, UserColorConstRef color) { SFZMessageDialogSmp dlg; SFCError error(SFERR_NO_ERROR); if ((error = MakeDialogFrame(title)) == SFERR_NO_ERROR) { if ((dlg = SFZMessageDialog::NewInstance(&error)) != null) { error = dlg->SetParent(GetThis()); if (error == SFERR_NO_ERROR) { error = dlg->SetFrame(_dialogFrame); if (error == SFERR_NO_ERROR) { error = dlg->RegisterHandler( SFXEventRange(SFEVT_RESPONDER_RESULT, SFEVT_RESPONDER_RESULT, SFP16_BEGIN, SFP16_END), XANDLER_INTERNAL(OnDialogResult) ); if (error == SFERR_NO_ERROR) { error = dlg->SetMessageText("Color Changed."); if (error == SFERR_NO_ERROR) { error = dlg->SetButtonText("OK"); if (error == SFERR_NO_ERROR) { // *** added code segments are in bold // set the bevel color of the frame header _dialogFrame->SetHeaderColor(SFXBevelColor(color.light, color.titleBack, color.dark)); // set the color of the frame title _dialogFrame->SetTextColor(color.titleFore); dlg->SetBackgroundColor(color.selBack); // ...(omitted)... } } } } } } } return error; }
Caution | |
---|---|
The handler of the dialog and its frame does not set the color scheme. This is because an event of the distribute type will not be distributed to responders created newly in the same event loop. |
That is all about implementation of this sample.
The following is execution result on BREW simulator.
The sample code in this chapter is available at this site.
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |