Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

Forums:

HI

I had used the below code to handle menus using list container but not able to handle key events. can anyone suggest how to achieve it????

 

 

/*-----------------------------------------------------------------------------
Includes and Variable Definitions
-----------------------------------------------------------------------------*/
#include "AEEModGen.h"          // Module interface definitions.
#include "AEEAppGen.h"          // Applet interface definitions.
#include "AEEShell.h"           // Shell interface definitions.  

#include "listcontainerapp.bid"
#include "listcontainerapp_res.h"

#include "AEEStdLib.h"

//List container and widgets includes
#include "AEEITypedListModelFactory.h"
#include "AEEITypedListModel.h"
#include "AEEIListContainerModelFactory.h"
#include "AEEIListContainerModel.h"
#include "AEEIVectorModel.h"
#include "AEEIModel.h"
#include "AEEIValueModel.h"

#include "AEEListContainer.bid"
#include "AEEVectorModel.bid"
#include "AEETypedListModelFactory.bid"
#include "AEEListContainerModelFactory.bid"
#include "AEEListWidget.h"
#include "AEETypedValueModel.bid"

#include "AEEIWidget.h"
#include "AEEIRootContainer.h"
#include "AEEIPropContainer.h"
#include "AEEIDisplayCanvas.h"
#include "AEEIDecorator.h"
#include "AEEImageWidget.h"
#include "AEEIXYContainer.h"
#include "AEEStaticWidget.h"

#include "AEEWidgetProperties.h"
#include "AEEResFile.bid"
#include "AEERootContainer.bid"
#include "AEEImageWidget.bid"
#include "AEEDisplayCanvas.bid"
#include "AEEPropContainer.bid"
#include "AEEStaticWidget.bid"
#include "AEEModel.bid"
#include "AEEPointerHelpers.h"
#include "AEEWidgetElement.h"
#include "AEEXYContainer.bid"
#include "AEEWidgetTCProperties.h"
// generic free memory function
#ifndef VF_FREE
#define VF_FREE      (GET_HELPER()->free)
#endif

// Error handling macros
#define ERR_CATCH        __errcatch
#define ERR_TRY(x)       do { nErr = (x); if (AEE_SUCCESS != nErr) goto ERR_CATCH; } while(0)
#define ERR_THROW(e)     do { nErr = (e); goto ERR_CATCH; } while(0)
#define ERR_CHECK_PTR(p) if (NULL == p) { ERR_THROW(AEE_EFAILED); }

#ifndef RELEASEIF
#define RELEASEIF(p)       listcontainerapp_ReleaseIf((IBase**)(void **)&p)
static void listcontainerapp_ReleaseIf(IBase **ppif) {
   if (*ppif) {
      IBASE_Release(*ppif);
      *ppif = 0;
   }

#endif

#ifndef ADDREFIF
#define ADDREFIF(p)        do { if (p) IBASE_AddRef((IBase*) (void *) p); } while(0)
#endif

// clean casting macro
#ifndef CAST
#define CAST(t, exp)   ((t)(void*)(exp))
#endif

typedef struct WidgetList{
   IWidget     *piwName;
   IWidget     *piwCmpny;
   IWidget     *piwImg;
   IResFile    *piResFile;
 WidgetList;

typedef  struct userContext
{
   IVectorModel   *piVectorModel;
   IShell         *piShell;
   ModelListener  ml[10];
   WidgetList     piwList[10];
   int            nmlCount;

   IResFile       *piResFile;
 userContext;


typedef struct _listcontainerapp {
    AEEApplet  Applet;    // First element of this structure must be AEEApplet.
    IDisplay * piDisplay; // Copy of IDisplay Interface pointer for easy access.
    IShell   * piShell;   // Copy of IShell Interface pointer for easy access.
    AEEDeviceInfo  deviceInfo; // Copy of device info for easy access.
    // Add your own variables here...
	IWidget        *piwRoot;
    IRootContainer *picRoot;
	IWidget        *piwListC;

	userContext       lcUserCtx;

 listcontainerapp;

typedef struct _CustomData
{
   int     nIdName;
   int     nIdCmpny;
   int     nIdImg;
 CustomData;

/*-----------------------------------------------------------------------------
Function Prototypes
-----------------------------------------------------------------------------*/
static  boolean listcontainerapp_HandleEvent(listcontainerapp* pMe, AEEEvent eCode,
                                                uint16 wParam, uint32 dwParam);
boolean listcontainerapp_InitAppData(listcontainerapp* pMe);
void    listcontainerapp_FreeAppData(listcontainerapp* pMe);
static void listcontainerapp_DrawScreen(listcontainerapp * pMe);

static int listcontainerapp_CreateListContainer(listcontainerapp *me);
/*-----------------------------------------------------------------------------
Function Definitions
-----------------------------------------------------------------------------*/


int AEEClsCreateInstance(AEECLSID ClsId, IShell * piShell, IModule * piModule, 
						 void ** ppObj)
{
    *ppObj = NULL;

    // Confirm this applet is the one intended to be created (classID matches):
    if( AEECLSID_LISTCONTAINERAPP == ClsId ) {
        // Create the applet and make room for the applet structure.
        // NOTE: FreeAppData is called after EVT_APP_STOP is sent to HandleEvent.
	    if( TRUE == AEEApplet_New(sizeof(listcontainerapp),
                        ClsId,
                        piShell,
                        piModule,
                        (IApplet**)ppObj,
                        (AEEHANDLER)listcontainerapp_HandleEvent,
                        (PFNFREEAPPDATA)listcontainerapp_FreeAppData) ) {
                     		
            // Initialize applet data. This is called before EVT_APP_START is
            // sent to the HandleEvent function.
		    if(TRUE == listcontainerapp_InitAppData((listcontainerapp*)*ppObj)) {
			    return AEE_SUCCESS; // Data initialized successfully.
		    }
		    else {
                // Release the applet. This will free the memory allocated for
                // the applet when AEEApplet_New was called.
                IApplet_Release((IApplet*)*ppObj);
                return AEE_EFAILED;
            }
        } // End AEEApplet_New
    }
    return AEE_EFAILED;




boolean listcontainerapp_InitAppData(listcontainerapp * pMe)
{
    // Save local copy for easy access:
    pMe->piDisplay = pMe->Applet.m_pIDisplay;
    pMe->piShell   = pMe->Applet.m_pIShell;

    // Get the device information for this handset.
    // Reference all the data by looking at the pMe->deviceInfo structure.
    // Check the API reference guide for all the handy device info you can get.
    pMe->deviceInfo.wStructSize = sizeof(pMe->deviceInfo);
    ISHELL_GetDeviceInfo(pMe->Applet.m_pIShell,&pMe->deviceInfo);
    
     return TRUE;// No failures up to this point, so return success.



void listcontainerapp_FreeAppData(listcontainerapp * me)
{
    // Insert your code here for freeing any resources you have allocated...
   RELEASEIF(me->picRoot);
   RELEASEIF(me->piwRoot);
   RELEASEIF(me->piwListC);



static boolean listcontainerapp_HandleEvent(listcontainerapp* pMe, 
								AEEEvent eCode, uint16 wParam, uint32 dwParam)
{  
    switch (eCode) {
        // Event to inform app to start, so start-up code is here:
        case EVT_APP_START:
            listcontainerapp_DrawScreen(pMe); // Draw text on display screen.
            return TRUE;         

        // Event to inform app to exit, so shut-down code is here:
        case EVT_APP_STOP:
      	    return TRUE;

        // Event to inform app to suspend, so suspend code is here:
        case EVT_APP_SUSPEND:
      	    return TRUE;

        // Event to inform app to resume, so resume code is here:
        case EVT_APP_RESUME:
            listcontainerapp_DrawScreen(pMe); // Redraw text on display screen.
      	    return TRUE;

        // An SMS message has arrived for this app. 
        // The Message is in the dwParam above as (char *).
        // sender simply uses this format "//BREW:ClassId:Message", 
        // example //BREW:0x00000001:Hello World
        case EVT_APP_MESSAGE:
      	    return TRUE;

        // A key was pressed:
        case EVT_KEY:
      	    return FALSE;

        // Clamshell has opened/closed
        // wParam = TRUE if open, FALSE if closed
        case EVT_FLIP:
            return TRUE;
      
	    // Clamtype device is closed and reexposed when opened, and LCD 
        // is blocked, or keys are locked by software. 
        // wParam = TRUE if keygaurd is on
        case EVT_KEYGUARD:
            return TRUE;

        // If event wasn't handled here, then break out:
        default:
            break;
    }
    return (pMe->piwRoot == NULL)?FALSE: IWidget_HandleEvent(pMe->piwRoot, eCode, wParam, dwParam);


static void listcontainerapp_DrawScreen(listcontainerapp * me)
{
   AEEResult nErr;
   AEERect  rect;
   IDisplayCanvas *piDisplayCanvas = NULL;
   ICanvas        *piCanvas        = NULL;

   SETAEERECT(&rect, 0, 0, me->deviceInfo.cxScreen, me->deviceInfo.cyScreen);

   // Create the root container that serves as the root of any widget tree
   ERR_TRY( ISHELL_CreateInstance(me->piShell, AEECLSID_RootContainer, (void**)&me->picRoot) );
   ERR_TRY( IRootContainer_QueryInterface(me->picRoot, AEEIID_IWidget, (void**)&me->piwRoot) );

   // And give it a display canvas to use so we can see the widgets get drawn to the screen
   ERR_TRY( ISHELL_CreateInstance(me->piShell, AEECLSID_DisplayCanvas, (void**)&piDisplayCanvas) );
   ERR_TRY( IDisplayCanvas_SetDisplay(piDisplayCanvas, me->piDisplay) );
   ERR_TRY( IDisplayCanvas_QueryInterface(piDisplayCanvas, AEEIID_ICanvas, (void**)&piCanvas) );
   IRootContainer_SetCanvas(me->picRoot, piCanvas, &rect);
   DBGPRINTF("Enable touch on root");

   ERR_TRY( IWidget_EnableTouch(me->piwRoot) );
   // Give our canvas a nice neutral color.
   ERR_TRY( IWidget_SetBGColor(me->piwRoot, MAKE_RGBA(0xCC, 0xCC, 0xCC, 0xFF)) );

   {
      WidgetPos    wp;
      WidgetExtent we = {0};

      wp.bVisible = TRUE;

      ERR_TRY( listcontainerapp_CreateListContainer(me) );
      
      wp.x  = 0;
      wp.y = 0;
	  ERR_TRY( IRootContainer_Insert(me->picRoot, me->piwListC, WIDGET_ZTOPMOST, &wp) );
      
   }

      // If there have been no failures up to this point then return success
ERR_CATCH:
   RELEASEIF(piCanvas);
   RELEASEIF(piDisplayCanvas);
   //return AEE_SUCCESS == nErr;


/********************************************
///////////////////////////////////////////
Create list container & widgets
*********************************************/
int IPropContainer_InsertEx(IPropContainer *me, IWidget *piw, uint16 nProp,
                                 boolean bVisible, int16 padBefore, int16 padAfter)
{
   AEEResult nErr;
   WidgetProp wp;
   wp.prop     = nProp;
   wp.bVisible = bVisible;

   IWidget_SetPreferredExtent(piw, NULL);

   ERR_TRY( IPropContainer_Insert(me, piw, WIDGET_ZNORMAL, &wp) );
   ERR_TRY( IPropContainer_SetPaddingExact(me, piw, padBefore, padAfter) );

ERR_CATCH:
   return nErr;


int IWidget_SetStaticText(IWidget* piw, const AECHAR* textValue)
{
   IValueModel *pivm = NULL;
   AEEResult nErr;

   if (NULL == piw) {
      return AEE_EBADPARM;
   }

   ERR_TRY( IWidget_GetModel(piw, AEEIID_IValueModel, CAST(IModel**, &pivm)) );

   IValueModel_SetValue(pivm, (void*)textValue, WSTRLEN(textValue), NULL);

ERR_CATCH:
   RELEASEIF(pivm);
   return nErr;

int listcontainerapp_CreateStaticWidget(IShell* piShell, const AECHAR* text, IWidget** ppiw, IFont *pif, uint32 flags)
{
   AEEResult nErr;

   ERR_TRY( ISHELL_CreateInstance(piShell, AEECLSID_StaticWidget, (void**)ppiw) );
   ERR_TRY( IWidget_SetFlags(*ppiw, flags) );

   if (NULL != pif) {
      ERR_TRY( IWidget_SetFont(*ppiw, pif) );
   }
   if (NULL != text) {
      ERR_TRY( IWidget_SetStaticText(*ppiw, text) );
   }
ERR_CATCH:
   if (AEE_SUCCESS != nErr) {
      RELEASEIF(*ppiw);
   }
   return nErr;

/*
Callback function to get the "item type" at a specific index.
*/
int listcontainerapp_GetItemType (void *pvCtx, int nIndex, int *pnType) 
{
   (void)nIndex;
   (void)pvCtx;
   *pnType = 1;
   return 0;


static int listcontainerapp_GetResString(IResFile *piResFile, int nResId, AECHAR **ppDest)
{
   AEEResult  nErr;
   AECHAR   *pwsz = NULL;
   uint32    nLen  = 0;



   ERR_TRY( IResFile_Get(piResFile, (uint32)nResId, RESTYPE_STRING, (AECHAR*)-1, &nLen) );

   if (nLen > 2) {
      pwsz = MALLOC(nLen);
      if (NULL == pwsz) {
         ERR_THROW(AEE_ENOMEMORY);
      }
   }

   ERR_TRY( IResFile_Get(piResFile, (uint32)nResId, RESTYPE_STRING, pwsz, &nLen) );

   *ppDest = pwsz;

ERR_CATCH:
   if (AEE_SUCCESS != nErr) {
      *ppDest = NULL;
      FREEIF(pwsz);
   }
   return nErr;


static int listcontainerapp_GetResImage(IResFile *piResFile, int nResId, IImage** ppDest)
{
   AEEResult nErr;
   void     *pObj = NULL;

   ERR_TRY( IResFile_GetObject(piResFile, (uint32)nResId, AEECLSID_VIEW, &pObj) );

   *ppDest = pObj;

ERR_CATCH:
   return nErr;


void listcontainerapp_ItemModelListener(WidgetList* me, ModelEvent *pEvent)
{
   AEEUID nType;
   CustomData *pValue; int nLen;
   AECHAR *pszTxt;
   IImage *pii = NULL;
   AEEResult nErr;

   ERR_TRY( ITypedValueModel_GetValue(CAST(ITypedValueModel *,pEvent->pModel), &nType, (void **)&pValue, &nLen));
   
   ERR_TRY( listcontainerapp_GetResString(me->piResFile, pValue->nIdName, &pszTxt));
   ERR_TRY( IWidget_SetStaticText(me->piwName, pszTxt) );

   ERR_TRY( listcontainerapp_GetResString(me->piResFile, pValue->nIdCmpny, &pszTxt) );
   ERR_TRY( IWidget_SetStaticText(me->piwCmpny, pszTxt) );

   ERR_TRY( listcontainerapp_GetResImage(me->piResFile, pValue->nIdImg, &pii) );
   ERR_TRY( IWidget_SetImage(me->piwImg, pii) );
   RELEASEIF(pii);
   
   ERR_CATCH:
;

/*
Callback function to get the "item widget" of certain type.
*/
int listcontainerapp_GetItemWidget(void *pvCtx, int nType, int nState, IWidget **ppiwItem) 
{
   ITypedValueModel *piTVM =NULL;
   WidgetExtent weStatic;
   userContext *pData = (userContext *)pvCtx;
   
   IPropContainer *picMainContainer = NULL;
   IValueModel    *pivm             = NULL;
   IWidget        *piwListItem      = NULL;
   IWidget        *piwName		     = NULL;
   IWidget        *piwImg      = NULL;
   IWidget        *piwCmpny          = NULL;
   int nErr;
   (void) nType; (void) nState;  
   pData->piwList[pData->nmlCount].piResFile = pData->piResFile;

   // Create the image
   ERR_TRY( ISHELL_CreateInstance(pData->piShell, AEECLSID_ImageWidget, (void**)&piwImg) );
   ERR_TRY( IWidget_SetFlags(piwImg, IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE) );
   pData->piwList[pData->nmlCount].piwImg = piwImg ;

   // Create static widget that holds the name
   ERR_TRY( listcontainerapp_CreateStaticWidget(pData->piShell, NULL, &piwName, 0,
                                              IDF_ALIGN_LEFT | IDF_ALIGN_TOP) );
   
   pData->piwList[pData->nmlCount].piwName = piwName;
   
   // Create static widget that holds the company name
   ERR_TRY( listcontainerapp_CreateStaticWidget(pData->piShell, NULL, &piwCmpny, 0,
                                              IDF_ALIGN_LEFT | IDF_ALIGN_TOP) );
   pData->piwList[pData->nmlCount].piwCmpny = piwCmpny;

    // Create Prop Container for list item
   ERR_TRY( ISHELL_CreateInstance(pData->piShell, AEECLSID_PropContainer, (void**)&picMainContainer) );

   //Insert the image into container
   ERR_TRY( IPropContainer_InsertEx(picMainContainer, piwImg, WIDGET_KEEP_EXTENT, TRUE, 0, 0) );

   // Insert from name and company into a container
   ERR_TRY( IPropContainer_InsertEx(picMainContainer, piwName, WIDGET_KEEP_EXTENT, TRUE, 2, 0) );
   ERR_TRY( IPropContainer_InsertEx(picMainContainer, piwCmpny, WIDGET_KEEP_EXTENT, TRUE, 2, 0) );

   ERR_TRY( IPropContainer_QueryInterface(picMainContainer, AEEIID_IWidget, (void**)&piwListItem) );
   ERR_TRY( IWidget_SetLayoutStyle(piwListItem, AEEWIDGET_LAYOUT_VERT) );

   ERR_TRY( IWidget_SetBorderWidth(piwListItem, 1) );
   ERR_TRY( IWidget_SetBorderColor(piwListItem, MAKE_RGBA(255, 255, 255, 180)) );

   ERR_TRY( IWidget_SetBGColor(piwListItem,       MAKE_RGBA(157, 204, 255, 200)) );

   ERR_TRY( IWidget_SetSelectedBGColor(piwListItem,       MAKE_RGBA( 73, 163, 255, 255)) );

   ERR_TRY( IWidget_SetShadowOffset(piwListItem, 0) );

   
   // CI TypedValueModel
   ERR_TRY( ISHELL_CreateInstance(pData->piShell, AEECLSID_TypedValueModel, (void**)&piTVM) );

   // Attach a TypedValueModel to this widget
   ERR_TRY( IWidget_SetModel(piwListItem, ITypedValueModel_to_IModel(piTVM)) );

   ERR_TRY( IModel_AddListenerEx(CAST(IModel *,piTVM), &pData->ml[pData->nmlCount], (PFNLISTENER)listcontainerapp_ItemModelListener, (void*)&pData->piwList[pData->nmlCount]) );
   // Set widget extent
   weStatic.width = 200;
   weStatic.height =  80;
   IWidget_SetExtent(piwListItem, &weStatic);

   *ppiwItem = piwListItem;
   ADDREFIF(*ppiwItem);
   pData->nmlCount++;

ERR_CATCH:
   RELEASEIF(piwListItem);
   RELEASEIF(piTVM);
   RELEASEIF(picMainContainer);
   RELEASEIF(pivm);
   RELEASEIF(piwListItem);
   RELEASEIF(piwImg);
   RELEASEIF(piwName);
   RELEASEIF(piwCmpny);
   return nErr;

/*
Callback function to get the "item data" for a specific index.
*/
int listcontainerapp_GetItemData(void *pvCtx, int nIndex, int nState, ITypedValueModel *piTVM) 
{
   userContext *pUserData = (userContext *)pvCtx;
   int nType = 0;
   int nErr = 0;
   CustomData *pData;
   (void) nState; 

  ERR_TRY( IVectorModel_GetAt(pUserData->piVectorModel, /*int32touint32*/nIndex, (void *)&pData) );
  ERR_TRY( listcontainerapp_GetItemType(pvCtx, nIndex, &nType) );
  ERR_TRY( ITypedValueModel_SetValue(piTVM, 100, pData, sizeof(CustomData *), NULL, NULL) );

ERR_CATCH:
   return nErr;

/*
Callback function to get total number of items in the list.
*/
int listcontainerapp_GetNumItems(void *pvCtx, int *pnNumItems) 
{
   userContext *pData = (userContext *)pvCtx;
   *pnNumItems = IVectorModel_Size(pData->piVectorModel);
   //*pnNumItems = 1;
   return 0;

/*
Callback function for cleaning up user context.
*/
void listcontainerapp_CleanUp(void *pvCtx)
{
   userContext *pData = (userContext *)pvCtx;
   RELEASEIF(pData->piVectorModel);
   RELEASEIF(pData->piResFile);


static void ListItem_Delete(CustomData *me)
{
   FREE(me);



static int listcontainerapp_InitUserContext(listcontainerapp *me)
{
   IVectorModel *piVectorModel;
   CustomData *pData = NULL;
   int i = 0;
   int nErr = 0;

   me->lcUserCtx.piShell = me->piShell;

   RELEASEIF(me->lcUserCtx.piResFile);
   ERR_TRY( ISHELL_CreateInstance(me->piShell, AEECLSID_ResFile, (void**)&me->lcUserCtx.piResFile) );
   ERR_TRY( IResFile_Open(me->lcUserCtx.piResFile , LISTCONTAINERAPP_RES_FILE) );

   ERR_TRY( ISHELL_CreateInstance(me->piShell, AEECLSID_VectorModel, (void**) &piVectorModel) );

   // Populate the vector model with the images & strings this list will display.
      for( i = 0; i < 5; i++) {
         pData = MALLOCREC(CustomData);
         if (NULL == pData) ERR_THROW(AEE_EFAILED);
         pData->nIdName =  IDS_STR_NAME_1 + i;
         pData->nIdCmpny = IDS_COMPANY_1  + i;
         pData->nIdImg = IDI_PHOTO_1 + i;
         ERR_TRY( IVectorModel_Add(piVectorModel, pData) );
      }

  (void)IVectorModel_SetPfnFree(piVectorModel, (PFNNOTIFY)ListItem_Delete);
   me->lcUserCtx.piVectorModel = piVectorModel;

ERR_CATCH:
	;
   return nErr;


static int listcontainerapp_CreateListContainer(listcontainerapp *me)
{
   IListContainerModelFactory *piLCMF = 0;
   IListContainerModel *piLCM = 0;
   IWidget *piw = 0;
   WidgetExtent extent;
   int nErr = 0;
   int i;
   
    RGBAVAL rgb_red = MAKE_RGBA(255,0,0,255); // red
    RGBAVAL rgb_blue = MAKE_RGBA(0,0,255,255); // green

    DBGPRINTF("Grid LC ClassID based");

    ERR_TRY( ISHELL_CreateInstance(me->Applet.m_pIShell, AEECLSID_ListContainer, (void**)&piw) );

   // Initialize user context
   ERR_TRY( listcontainerapp_InitUserContext(me) );

   // CI ListContainerModelFactory
   ERR_TRY( ISHELL_CreateInstance(me->Applet.m_pIShell, AEECLSID_ListContainerModelFactory, (void**)&piLCMF) );
    // Get ListContainerModel instance from CreateCallbackBased method of ListContainerModelFactory.
   (void ) IListContainerModelFactory_CreateCallbackBased (piLCMF, &me->lcUserCtx, 
                                         listcontainerapp_GetItemType, 
                                         listcontainerapp_GetItemWidget, 
                                         listcontainerapp_GetItemData, 
                                         listcontainerapp_GetNumItems,
                                         listcontainerapp_CleanUp,
                                         &piLCM);

   ERR_TRY( IWidget_SetModel(piw, IListContainerModel_to_IModel (piLCM)) );
  
   (void) IWidget_SetFlags(piw, LWF_PIXELSCROLL|LWF_LIVESCROLL );

   (void) IWidget_SetHintRows(piw, 10);
   IWidget_GetPreferredExtent(piw, &extent);
   extent.width = me->deviceInfo.cxScreen - 20;
   extent.height = me->deviceInfo.cyScreen - 20;
   IWidget_SetExtent(piw, &extent);

   (void) IWidget_SetBorderWidth(piw, 5);
   (void) IWidget_SetBorderColor(piw, rgb_red);
   (void) IWidget_SetPadding(piw, 5);
   (void) IWidget_SetBGColor(piw, rgb_blue);

   me->piwListC = piw;
   (void) IWidget_AddRef(me->piwListC);


ERR_CATCH:
   RELEASEIF(piw);
   RELEASEIF(piLCMF);
   RELEASEIF(piLCM);

   return nErr;

See https://developer.brewmp.com/forum/custom-items-list-container#comment-5...
If you looking for something else, please elaborate.

See https://developer.brewmp.com/forum/custom-items-list-container#comment-5...
If you looking for something else, please elaborate.