Resources | developer.brewmp.com Resources | developer.brewmp.com

Developer

resources

Creating a Custom Touch Controller

Base version:

Brew® MP 1.0.2

Tested version:

Brew MP 1.0.2

Phone tested:

No

This document describes how to create a custom touch controller to use in widget-based applications. Modifying the Brew MP UI Widgets code is strongly discouraged. Instead, it is recommended that your own touch controllers be implemented outside of Brew MP UI Widgets in their own extension.

Objective

This document explains how custom touch controllers can be created by using touch controllers from the Brew MP UI Widgets platform. This document references an implementation of a custom touch controller similar to the CheckTC (Touch Controller), which is provided in the Brew MP platform. The difference is that this touch controller selects the widget (like CheckWidget) on a pointer down event as oposed to on a pointer up event. This custom touch controller uses GenericTC as a base. This takes advantage of its provision-like click notifications.

Requirements

A simple way to create a custom touch controller is to create an extension using an existing Brew MP UI Touch Controller. The following steps provide an overview of what needs to be done to achieve this. Each step is described in more detail in the example. For more information on Brew MP extensions, see the C Extension Visual Studio Primer.

To create a custom touch controller

  1. Define the internal structure of the touch controller.
  2. Define the constructor of a custom touch controller.
  3. Set the widget.
  4. Customize event handling.
  5. Free memory.

Sample code location

ZIP filename

Location

Run app

c_customtouchcontroller_app

Brew MP Resources

  • Download and extract the ZIP file.

  • Compile the app.

  • Run it on the Brew MP Simulator.

Example: Define the internal structure of the touch controller.

The following structure is used by the custom touch controller provided in the sample code. It includes an IController virtual table. It also includes a pointer to IEnv, which provides system services like class instantiation. The IController pointer holds a reference to the base widget, which in this case is a GenericTC. It is used to override the event handling of the base controller, GenericTC.

typedef struct {   
   AEEVTBL(IController) *  pvt;   
   IController    *picBase;      //Base controller   
   IEnv           *piEnv;   
   IWidget        *piw;          //Controlled widget   
} CustomTouchController;

Example: Define the constructor of a custom touch controller.

The following code snippet shows how to create a custom touch controller with an existing touch controller. First, you need to create an instance of IEnv, which exists throughout the life of the widget. Then, IEnv is used to allocate the custom touch controller's main data structure. Finally, the base touch controller, GenericTC, is created.

static int CustomTouchController_New(IController **ppOut, IShell *piShell)   
{   
   CustomTouchController* me = NULL;   
   IEnv* piEnv = NULL;   
   int nErr = AEE_SUCCESS;   
   ERR_TRY( ISHELL_CreateInstance(piShell, AEECLSID_Env, (void **) &piEnv) );   
   
   //Create the our base structure wih an IController vtable   
   ERR_TRY( IENV_ERRMALLOCRECEX(piEnv,   
                                CustomTouchController,    
                                sizeof(AEEVTBL(IController)),   
                                (void**)&me) );   
   me->piEnv = piEnv;   
   IEnv_AddRef(piEnv);   
   
   
  nErr = IEnv_CreateInstance(piEnv,   
                             AEECLSID_GenericTC,   
                             (void **) &me->picBase);   
   
   if (nErr != AEE_SUCCESS || NULL == me->picBase) {   
      CustomTouchController_Dtor(me);   
      return nErr;   
   }

Next, IController vtable is created. All IController entries are forwarded to the base IController (GenericTC) except for two: SetWidget and HandleEvent. In SetWidget the controlled widget is captured for use later before sending it to the base controller. The event handler is explained below.

   me->pvt = GETVTBL(me,IController);   
   me->pvt->AddRef = CustomTouchController_AddRef;   
   me->pvt->Release = CustomTouchController_Release;   
   me->pvt->HandleEvent = CustomTouchController_HandleEvent;   
   me->pvt->SetHandler = CustomTouchController_SetHandler;   
   me->pvt->SetWidget = CustomTouchController_SetWidget;   
   me->pvt->QueryInterface = CustomTouchController_QueryInterface;   
   
   *ppOut = CAST(IController*, me);   
   
ERR_CATCH:      
   RELEASEIF(piEnv);   
   return nErr;   
}

Example: Set the widget.

Here the controller widget is captured before it is sent to the base controller. This is needed to control the widget from the custom touch controller's event handler.

static int CustomTouchController_SetWidget(IController *po, IWidget *piw)   
{   
   CustomTouchController* me = ICONTROLLER_TO_CUSTOMTOUCHCONTROLLER(po);   
   me->piw = piw; //no add ref. it will be ref'ed by the base   
   return IController_SetWidget(me->picBase, piw);   
}

Example: Customize event handling.

The behaviour of the base touch controller can be changed by modifying the way certain events are handled, or even ignoring certain events altogether. This is where property behaviour is customized to select the widget on pointer down.

Also, this shows how multi-touch support is added to a touch controller. By handling the property, PROPEX_TOUCH_SUPPORT, the touch controller will receive multi-touch events as long as the widget forwards its events to the controller.

static boolean CustomTouchController_HandleEvent(IController* po, 
            AEEEvent evt, uint16 wParam, uint32 dwParam)   
{   
   CustomTouchController* me = ICONTROLLER_TO_CUSTOMTOUCHCONTROLLER(po);   
   int nErr = AEE_SUCCESS;   
   boolean bHandled = FALSE;   
   //toggle selection on pointer down   
   if (EVT_POINTER_DOWN == evt) {   
      IValueModel *pivm;   
      boolean bPressed;   
      ERR_TRY( IWidget_GetModel(me->piw, AEEIID_IValueModel, CAST(IModel**,&pivm)) );   
      //toggle selected state   
      bPressed = !IValueModel_GetBool(pivm);   
      IValueModel_SetBool(pivm, bPressed);   
      bHandled = TRUE;   
      RELEASEIF(pivm);   
   }   
   //support multi-touch   
   if (EVT_WDG_GETPROPERTY == evt) {   
      if (PROP_EX == wParam) {   
         WidgetPropEx *pPropEx = (WidgetPropEx*) dwParam;   
         if (PROPEX_TOUCH_SUPPORT == pPropEx->nPropId) {   
            *((int*) pPropEx->pUser) = AEEWIDGET_TOUCH_SUPPORT_MULTIPLE_POINTERS;   
            return TRUE;   
         }    
      }   
   }   
   if (!bHandled) {   
      bHandled = IController_HandleEvent(me->picBase, evt, wParam, dwParam);   
   }   
ERR_CATCH:   
   if (AEE_SUCCESS != nErr) {   
      bHandled = FALSE;   
   }   
   return bHandled;   
}

Example: Free memory.

The destructor releases only the IEnv not IController or IWidget. The base IController is the first one to destructed as it is the one doing the reference counting. IWidget is only referenced by the base IController so it does not need to be released.

static void CustomTouchController_Dtor(CustomTouchController *me)   
{   
   IEnv *piEnv = me->piEnv;   
   me->piEnv = NULL;   
   (void) IEnv_Free(piEnv, me);   
   IEnv_Release(piEnv);   
}

Related information

  • See the Widgets Touch Technology Guide
  • See the C Extension Visual Studio Primer