📄 mfw_mnu.c
字号:
{
mnu->lCursor[mnu->level] = 0;
mnu->flags |= E_MNU_BOTTOMED;
if (mnu->handler)
if (mnu->mask & E_MNU_BOTTOMED)
mnu->handler(E_MNU_BOTTOMED,mnu);
}
else
{
mnu->lCursor[mnu->level] += (U8) 1;
mnu->flags &= ~E_MNU_BOTTOMED;
}
ci = ca->items + mnu->lCursor[mnu->level];
} while (ci->flagFunc(mnu,ca,ci) & MNU_ITEM_HIDE);
if (mnu->scrollMode) /* Simple scrolling */
{
U8 shift = mnu->lShift[mnu->level];
U8 index = countVisible(mnu,ca,mnu->lCursor[mnu->level]);
U8 visibleItems = countVisible(mnu,ca,ca->nItems);
int nLines = mnu->nLines;
if (visibleItems<nLines)
nLines = visibleItems;
if (shift<nLines)
shift++;
mnu->lShift[mnu->level] = shift;
}
mnuUpdate(mnu);
return MfwResOk;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : mnuSelect |
+--------------------------------------------------------------------+
PURPOSE : select a menu item; if there is a submenu, go one level
down
*/
MfwRes mnuSelect (MfwHnd m)
{
MfwMnu *mnu;
MfwMnuAttr *submenu, *ca;
MenuFunc func;
U8 dsplOld;
if ((mnu = mfwControl(m)) == 0)
return MfwResIllHnd;
ca = mnu->curAttr;
submenu = ca->items[mnu->lCursor[mnu->level]].menu;
func = ca->items[mnu->lCursor[mnu->level]].func;
if (func) /* perform submenu */
{
func(mnu,&ca->items[mnu->lCursor[mnu->level]]);
}
if (submenu) /* call menu function */
{
if (menuIsEmpty(mnu,submenu))
{
mnu->flags |= E_MNU_EMPTY;
if (mnu->handler && mnu->mask & E_MNU_EMPTY)
mnu->handler(E_MNU_EMPTY,mnu);
mnu->flags &= ~E_MNU_EMPTY;
}
else
{
dspl_Clear(ca->area->px, ca->area->py,
(U16) (ca->area->sx+ca->area->px-1),
(U16) (ca->area->sy+ca->area->py-1));
mnu->level++;
mnu->lCursor[mnu->level] = 0;
ca = mnu->curAttr = submenu;
if (ca->items->flagFunc(mnu,ca,ca->items) & MNU_ITEM_HIDE)
mnuDown(m);
else
mnuUpdate(mnu);
}
return MfwResOk; /* we do not have to check for !submenu */
}
if (!func && !submenu) /* inform mmi */
{
mnu->flags |= E_MNU_SELECT;
if (mnu->handler && mnu->mask & E_MNU_SELECT)
mnu->handler(E_MNU_SELECT,mnu);
}
return MfwResOk;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : mnuEscape |
+--------------------------------------------------------------------+
PURPOSE : go back one level or leave the menu
*/
MfwRes mnuEscape (MfwHnd m)
{
MfwMnu *mnu;
MfwMnuAttr *attr;
U8 lvl;
U8 dsplOld;
if ((mnu = mfwControl(m)) == 0)
return MfwResIllHnd;
if (mnu->level != 0)
{
mnu->lCursor[mnu->level] = UNUSED;
mnu->lShift[mnu->level] = 1;
mnu->level--;
lvl = 0; /* set level 0 */
attr = mnu->attr; /* set start point */
while (lvl != mnu->level)
{
attr = attr->items[mnu->lCursor[lvl]].menu;
lvl++;
}
mnu->curAttr = attr;
mnuUpdate(mnu);
}
else
{
mnu->flags |= E_MNU_ESCAPE;
if (mnu->handler)
if (mnu->mask & E_MNU_ESCAPE)
mnu->handler(E_MNU_ESCAPE,mnu);
}
return MfwResOk;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : mnuDone |
+--------------------------------------------------------------------+
PURPOSE : reset menu
*/
MfwRes mnuDone (MfwHnd m)
{
MfwMnu *mnu;
if ((mnu = mfwControl(m)) == 0)
return MfwResIllHnd;
mnu->curAttr = mnu->attr;
mnu->level = 0;
memset(mnu->lCursor,UNUSED,sizeof(mnu->lCursor));
memset(mnu->lShift,1,sizeof(mnu->lShift));
mnu->lCursor[0] = 0;
return MfwResOk;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : mnuKeyAction |
+--------------------------------------------------------------------+
PURPOSE : perform direct jumping if there was pressed KCD_1
through KCD_9; in this case function returns 1;
otherwise function returns 0
*/
MfwRes mnuKeyAction (MfwHnd m, U8 keycode)
{
MfwMnu *mnu;
U8 directAccess;
if ((mnu = mfwControl(m)) == 0)
return MfwResIllHnd;
switch (keycode)
{
case KCD_1: directAccess = 0; break;
case KCD_2: directAccess = 1; break;
case KCD_3: directAccess = 2; break;
case KCD_4: directAccess = 3; break;
case KCD_5: directAccess = 4; break;
case KCD_6: directAccess = 5; break;
case KCD_7: directAccess = 6; break;
case KCD_8: directAccess = 7; break;
case KCD_9: directAccess = 8; break;
default: return 0;
}
if (directAccess >= mnu->curAttr->nItems)
return 0;
mnu->lCursor[mnu->level] = directAccess;
mnuShow(m);
mnuSelect(m);
return 1;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : mnuChooseItem |
+--------------------------------------------------------------------+
PURPOSE : Chooses the nItemst Item.
*/
MfwRes mnuChooseVisibleItem(MfwHnd m,U8 nItem)
{
MfwMnu *mnu;
int i;
if ((mnu = mfwControl(m)) == 0)
return MfwResIllHnd;
if (nItem<0)
return MfwResIllHnd;
for (i = 0; i < mnu->curAttr->nItems; i++)
{
if (!(mnu->curAttr->items[i].flagFunc(mnu,
mnu->curAttr,
&(mnu->curAttr->items[i]))
& MNU_ITEM_HIDE))
{
if (!nItem)
{
mnu->lCursor[mnu->level] = i;
mnuUpdate(mnu);
return MfwResOk;
}
else
nItem--;
}
}
return MfwResIllHnd;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : menuIsEmpty |
+--------------------------------------------------------------------+
PURPOSE : check for empty submenu
*/
static int menuIsEmpty (MfwMnu *m, MfwMnuAttr *ma)
{
int i;
for (i = 0; i < ma->nItems; i++)
if (!(ma->items[i].flagFunc(m,ma,&(ma->items[i]))
& MNU_ITEM_HIDE))
return 0;
return 1;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : countVisible |
+--------------------------------------------------------------------+
PURPOSE : count visible items up to current item
*/
static int countVisible (MfwMnu *m, MfwMnuAttr *ma, int start)
{
int i, count;
for (i = 0, count = 0; i < start; i++)
if (!(ma->items[i].flagFunc(m,ma,&(ma->items[i]))
& MNU_ITEM_HIDE))
count++;
return count;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : countVisibleItems |
+--------------------------------------------------------------------+
PURPOSE : count visible items in the current branch
*/
U8 mnuCountVisibleItems (MfwHnd m)
{
MfwMnu *mnu;
if ((mnu = mfwControl(m)) == 0)
return 0;
return (U8)countVisible(mnu, mnu->curAttr,mnu->curAttr->nItems);
}
/*
+--------------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : countCurrentVisibleItem |
+--------------------------------------------------------------------------+
PURPOSE : returns the position of the current Item
*/
U8 mnuCountCurrentVisibleItem(MfwHnd m)
{
MfwMnu *mnu;
U8 i;
U8 pos=0;
if ((mnu = mfwControl(m)) == 0)
return 0;
for (i = 0; i < mnu->curAttr->nItems; i++)
{
if ((mnu->lCursor[mnu->level]) == i)
return pos;
if (!(mnu->curAttr->items[i].flagFunc(mnu,
mnu->curAttr,
&(mnu->curAttr->items[i]))
& MNU_ITEM_HIDE))
pos++;
}
return pos;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : checkPredraw |
+--------------------------------------------------------------------+
PURPOSE : check / generate predraw event
*/
static int checkPredraw (MfwMnu *mnu, MfwMnuItem *mi,
char **t, MfwIcnAttr **icn)
{
int res = 0;
if (mi->flagFunc(mnu,mnu->curAttr,mi) & MNU_ITEM_NOTIFY)
{
mnu->flags |= E_MNU_PREDRAW;
if (mnu->handler)
if (mnu->mask & E_MNU_PREDRAW)
{
if (mi->exta)
{
((MfwItmExtPredraw*)(mi->exta))->str = *t;
((MfwItmExtPredraw*)(mi->exta))->icon = *icn;
}
res = mnu->handler(E_MNU_PREDRAW,mi);
if (mi->exta)
{
*t = ((MfwItmExtPredraw*)(mi->exta))->str;
*icn = ((MfwItmExtPredraw*)(mi->exta))->icon;
}
}
mnu->flags &= ~E_MNU_PREDRAW;
}
return res;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : checkPostdraw |
+--------------------------------------------------------------------+
PURPOSE : check / generate postdraw event
*/
static int checkPostdraw (MfwMnu *mnu, MfwMnuItem *mi)
{
int res = 0;
if (mi->flagFunc(mnu,mnu->curAttr,mi) & MNU_ITEM_NOTIFY)
{
mnu->flags |= E_MNU_POSTDRAW;
if (mnu->handler)
if (mnu->mask & E_MNU_POSTDRAW)
res = mnu->handler(E_MNU_POSTDRAW,mi);
mnu->flags &= ~E_MNU_POSTDRAW;
}
return res;
}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417) MODULE : MFW_MNU |
| STATE : code ROUTINE : checkStatus |
+--------------------------------------------------------------------+
PURPOSE : check / insert item status (string MUST be in RAM)
SPR998 - SH - Changed to allow checkbox menu items.
*/
static int checkStatus (MfwMnu *m, MfwMnuAttr *ma, MfwMnuItem *mi,
char *menuString)
{
char *e; /* ES!! UNICODE */
int index;
BOOL unicode;
U16 flagResult;
if (menuString[0] == 0x80)
unicode = TRUE;
else
unicode = FALSE;
flagResult = mi->flagFunc(m,ma,mi);
switch (flagResult)
{
case MNU_ITEM_STATED:
e = mi->exta;
if (!e)
return 0;
while (menuString[index])
{
if (menuString[index] == '%') /* ES!! : UNICODE */
{
switch (menuString[index+1])
{
case 'c': /* single char */
strcpy(&menuString[index+1],&menuString[index+2]);
menuString[index] = *e;
e++;
break;
}
}
index++;
}
break;
/* SPR998 - SH - Checked or unchecked option.
* Don't need to do anything here. */
case MNU_ITEM_UNCHECKED:
case MNU_ITEM_CHECKED:
break;
default:
break;
}
return flagResult; /* SPR#998 - SH - Now returns item type */
}
static void mnuDrawHeader(MfwMnuAttr *mnuAttr, MfwRect* areaLeft, char *hdrString)
{
int mode = mnuAttr->mode;
MfwRect* mnuArea = mnuAttr->area;
int mnuColour = mnuAttr->mnuColour;
char* txt=hdrString;
int nPixels;
int xPos,yPos,sx,sy,txtLen,txtXpos;
xPos = mnuArea->px;
yPos = mnuArea->py;
sy = res_getTitleHeight();
resources_setTitleColour(mnuColour);
dspl_Clear(xPos,yPos,(U16)(mnuArea->sx+xPos-1),(U16)(mnuArea->sy+yPos-1));
if ((mode & MNU_HDR_ALIGN) == MNU_HDR_LEFT)
{
//Position is correct
txtXpos = xPos;
}
else
{
nPixels = dspl_GetTextExtent( txt, 0);
if ((mode & MNU_HDR_ALIGN) == MNU_HDR_RIGHT)
{
txtXpos = xPos + mnuArea->sx - nPixels;
}
else
{ //Display in middle
txtXpos = xPos + (mnuArea->sx - nPixels)/2;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -