📄 consoleoutlook.c
字号:
#include <comsub.h>
#include <ui.h>
#include <nv.h>
#include <osd.h>
#include <ui_sub.h>
#include <panel.h>
#include <rscstruc.h>
#include <resource.h>
#include <platform.h>
#include <fileopen.h>
#include "normal.h"
#include "NMOSD.h"
#include <string.h>
#include "../fileopenmenu/GuiControl.h"
#include<guiddi.h>
#include <gui.h>
#include <UIOSD.h>
extern const DWORD g_DDI_16_DefPalette[16];
extern const BYTE Map256To16[256];
extern BYTE cnsl_cur_item;
//extern BYTE vcdcnsl_cur_item;
extern const UINT GUI_LANGUAGEID[13];
extern BOOL cursound;
#define cnsl_cur_item_id (menus[cnsl_cur_item].ID)
#define cnsl_item_id(i) (menus[i].ID)
#if 0
BaseRect brc[CNSL_BOX_NUMS_DVD]; //for DVD console box
BaseBmp bmpbox[CNSL_BOX_NUMS_DVD]; //for DVD console box's bmp
BaseRect vcdbrc[CNSL_BOX_NUMS_VCD]; //for VCD console box
BaseBmp vcdbmpbox[CNSL_BOX_NUMS_VCD]; //for VCD console box's bmp
#endif
//extern MENUITEM *menus;
extern MENUITEM menus[];
extern BYTE menu_count;//count of menus
//modified by jane
BaseRect hintRect[]=
{
{{CNSL_BOX_UPPERLEFT,CNSL_UPHINTBOX_TOP,CNSL_HINTBOX_RIGHT,CNSL_DOWNHINTBOX_TOP},242,61,104},
{{CNSL_BOX_UPPERLEFT,CNSL_DOWNHINTBOX_TOP+1,CNSL_HINTBOX_RIGHT,CNSL_DOWNHINTBOX_BOTTOM},243,243,243}
};
HintStrInfo downHintStr[10]=
{
{4,10,0,{0xe0,0x19,0x00,' ',0x00,0x00},1,SPECIAL_STR_WIDTH,32,TEXTFORMAT_RIGHT},//UP/DWON icon
{34,11,RS_GUI_MOVE,{0x00,'M',0x00,'o',0x00,'v',0x00,'e',0x00,0x00},4,NORMAL_STR_WIDTH,30,TEXTFORMAT_LEFT},//move
{124,11,0,{0xe0,0x14,0x00,0x00},1,SPECIAL_STR_WIDTH,32,TEXTFORMAT_RIGHT},//INPUT icon
{158,11,RS_GUI_INPUT,{0x00,'I',0x00,'n',0x00,'p',0x00,'u',0x00,'t',0x00,0x00},5,NORMAL_STR_WIDTH,30,TEXTFORMAT_LEFT},//select
{232,8,0,{0xe0,0x13,0x00,0x00},1,SPECIAL_STR_WIDTH,32,TEXTFORMAT_RIGHT},//ENTER icon
{266,11,RS_GUI_ENTER,{0x00,'E',0x00,'n',0x00,'t',0x00,'e',0x00,'r',0x00,0x00},5,NORMAL_STR_WIDTH,30,TEXTFORMAT_LEFT},//enter
{124,11,0,{0xe0,0x15,0xe0,0x16,0x00,0x00},1,SPECIAL_STR_WIDTH,32,TEXTFORMAT_RIGHT},//LEFT/RIGHT icon
{158,11,RS_GUI_SELECT,{0x00,'S',0x00,'e',0x00,'l',0x00,'e',0x00,'c',0x00,'t',0x00,0x00},6,NORMAL_STR_WIDTH,30,TEXTFORMAT_LEFT}//select
};
HintStrInfo upHintStr=
{
HINT_TITLE_STR_XOFFSET,
HINT_TITLE_STR_YOFFSET,
0,
{0},
0,
NORMAL_STR_WIDTH,
30,
DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CHARCLIP
};
HintBox hintbox=
{
&hintRect[0],
&hintRect[1],
&upHintStr,
{&downHintStr[0],&downHintStr[1],&downHintStr[2],&downHintStr[3],&downHintStr[4],&downHintStr[5] },
6
};
EXTERN MLineConsItem consoleAudioItem;
BYTE timestr[]={
0x00,'-',0x00,0x3a,
0x00,'-',0x00,'-',0x00,0x3a,
0x00,'-',0x00,'-',0x00,0x00
/*
' ','-',' ',' ',
' ','-',' ','-',' ',' ',
' ','-',' ','-',' ',' '
*/ };
/*----------------------------------------------------------------------------
* Function name: ShowBoxWithMemdc
* Arguments: HDC hdc,lpBaseRect brect,lpBaseBmp bmp,BYTE* str, BOOL symbol
* Return value: None
* Remark: show base box with memory dc.
comment by chena: draw menuitem. if symbol is true, also draw arrows
*----------------------------------------------------------------------------*/
#if 1
void ShowBoxWithMemdc(HDC hdc,LPMENUITEM pMenuItem,BYTE* str, BOOL symbol)
{
RECT BmpRect,StrRect,ArrowRect,TempRect;
HDC hMemDC;
HBITMAP hOldBmp;
COLORREF clText;
COLORREF clBack;
COLORREF clHighLight;
COLORREF clWrite;
BYTE leftarrow[4]={0xe0,0x10,0x00,0x00};
BYTE rightarrow[4]={0xe0,0x11,0x00,0x00};
clText=GetColorInDef256Palette(pMenuItem->baseRect.strColor);
clBack=g_DDI_16_DefPalette[Map256To16[CNSL_BOX_BKCOLOR]];//GetColorInDef256Palette(CNSL_BOX_BKCOLOR);
clHighLight=g_DDI_16_DefPalette[Map256To16[CNSL_BOX_HLCOLOR]];//GetColorInDef256Palette(CNSL_BOX_HLCOLOR);
clWrite=g_DDI_16_DefPalette[Map256To16[CNSL_BOX_WHCOLOR]];//GetColorInDef256Palette(CNSL_BOX_WHCOLOR);
SetRect(&BmpRect, pMenuItem->baseBmp.upperleftx, pMenuItem->baseBmp.upperlefty, pMenuItem->baseBmp.upperleftx+pMenuItem->baseBmp.width, pMenuItem->baseBmp.upperlefty+pMenuItem->baseBmp.height);
CopyRect(&StrRect, &(pMenuItem->baseRect.rect));
hMemDC=InitMemoryDC(hdc, StrRect.right-StrRect.left, StrRect.bottom-StrRect.top, &hOldBmp);
if(hMemDC == 0){
//printf("create hMemDC failed.\r\n");
return;
}
//set TempRect
TempRect.left=0;
TempRect.top=0;
TempRect.right=StrRect.right-StrRect.left;
TempRect.bottom=StrRect.bottom-StrRect.top;
//draw the item
if(pMenuItem->baseRect.bkColor==CNSL_BOX_BACKCOLOR_HIGHLIGHT)
{
GUI_CreateButtonControl2(hMemDC,&TempRect,clHighLight,clHighLight,clHighLight,clText ,str,UNICODE_STRING, DT_RIGHT, MLCSI_TXT_RIGHT_MG);
if(symbol)
{
ArrowRect.top = TempRect.top;
ArrowRect.bottom = TempRect.bottom;
ArrowRect.left = TempRect.left + MLCSI_ARROW_LEFT;
ArrowRect.right = ArrowRect.left + MLCSI_ARROW_WIDTH;
GUI_CreateButtonControl2(hMemDC,&ArrowRect,CL_BKNOCARE,CL_BKNOCARE,CL_BKNOCARE, clText,leftarrow,UNICODE_STRING, 0, 0);
OffsetRect(&ArrowRect, MLCSI_ARROW_INTERVAL, 0);
GUI_CreateButtonControl2(hMemDC,&ArrowRect,CL_BKNOCARE,CL_BKNOCARE,CL_BKNOCARE, clText,rightarrow,UNICODE_STRING, 0, 0);
}
}
else
{
GUI_CreateButtonControl2(hMemDC,&TempRect,clBack,clBack,clBack,clText ,str,UNICODE_STRING, DT_RIGHT, MLCSI_TXT_RIGHT_MG);
}
TempRect.left=BmpRect.left-StrRect.left;
TempRect.top=BmpRect.top-StrRect.top;
TempRect.right=BmpRect.right-StrRect.left;
TempRect.bottom=BmpRect.bottom-StrRect.top;
GUI_CreateBitmapControl2(hMemDC,&TempRect,CL_BKNOCARE, CL_BKNOCARE, CL_BKNOCARE, (UINT)pMenuItem->baseBmp.lpBitmapName, 0, 0);
BitBlt(hdc, StrRect.left, StrRect.top, StrRect.right-StrRect.left, StrRect.bottom-StrRect.top, hMemDC, 1,0,SRCCOPY);
DelMemoryDC(hMemDC, hOldBmp);
//draw a line
/*
// if((StrRect.bottom<CNSL_BOX_UPPERTOP+6*(CNSL_BOX_HIGH+3)+CNSL_BOX_AUDIO_HIGH-10)&&(g_UiCoreState!=UI_CORE_STOP))
{
TempRect.left=StrRect.left;
TempRect.top=StrRect.bottom+1;
TempRect.right=StrRect.right-2;
TempRect.bottom=StrRect.bottom+3;
GUI_CreateButtonControl(hdc,&TempRect,clWrite,clWrite,clWrite,clText ,"",UNICODE_STRING, 0, 0);
}
*/
}
#else
void ShowBoxWithMemdc(HDC hdc,lpBaseRect brect,lpBaseBmp bmp,BYTE* str, BOOL symbol)
{
RECT BmpRect,StrRect,ArrowRect,TempRect;
HDC hMemDC;
HBITMAP hOldBmp;
COLORREF clText;
COLORREF clBack;
COLORREF clHighLight;
COLORREF clWrite;
BYTE leftarrow[4]={0xe0,0x10,0x00,0x00};
BYTE rightarrow[4]={0xe0,0x11,0x00,0x00};
clText=GetColorInDef256Palette(brect->strColor);
clBack=g_DDI_16_DefPalette[Map256To16[CNSL_BOX_BKCOLOR]];//GetColorInDef256Palette(CNSL_BOX_BKCOLOR);
clHighLight=g_DDI_16_DefPalette[Map256To16[CNSL_BOX_HLCOLOR]];//GetColorInDef256Palette(CNSL_BOX_HLCOLOR);
clWrite=g_DDI_16_DefPalette[Map256To16[CNSL_BOX_WHCOLOR]];//GetColorInDef256Palette(CNSL_BOX_WHCOLOR);
SetRect(&BmpRect, bmp->upperleftx, bmp->upperlefty, bmp->upperleftx+bmp->width, bmp->upperlefty+bmp->height);
CopyRect(&StrRect, &(brect->rect));
hMemDC=InitMemoryDC(hdc, StrRect.right-StrRect.left, StrRect.bottom-StrRect.top, &hOldBmp);
TempRect.left=0;
TempRect.top=0;
TempRect.right=StrRect.right-StrRect.left;
TempRect.bottom=StrRect.bottom-StrRect.top;
if(brect->bkColor==CNSL_BOX_BACKCOLOR_HIGHLIGHT)
{
GUI_CreateButtonControl2(hMemDC,&TempRect,clHighLight,clHighLight,clHighLight,clText ,str,UNICODE_STRING, DT_RIGHT, MLCSI_TXT_RIGHT_MG);
if(symbol)
{
ArrowRect.top = TempRect.top;
ArrowRect.bottom = TempRect.bottom;
ArrowRect.left = TempRect.left + MLCSI_ARROW_LEFT;
ArrowRect.right = ArrowRect.left + MLCSI_ARROW_WIDTH;
GUI_CreateButtonControl2(hMemDC,&ArrowRect,CL_BKNOCARE,CL_BKNOCARE,CL_BKNOCARE, clText,leftarrow,UNICODE_STRING, 0, 0);
OffsetRect(&ArrowRect, MLCSI_ARROW_INTERVAL, 0);
GUI_CreateButtonControl2(hMemDC,&ArrowRect,CL_BKNOCARE,CL_BKNOCARE,CL_BKNOCARE, clText,rightarrow,UNICODE_STRING, 0, 0);
}
}
else
{
GUI_CreateButtonControl2(hMemDC,&TempRect,clBack,clBack,clBack,clText ,str,UNICODE_STRING, DT_RIGHT, MLCSI_TXT_RIGHT_MG);
}
TempRect.left=BmpRect.left-StrRect.left;
TempRect.top=BmpRect.top-StrRect.top;
TempRect.right=BmpRect.right-StrRect.left;
TempRect.bottom=BmpRect.bottom-StrRect.top;
GUI_CreateBitmapControl2(hMemDC,&TempRect,CL_BKNOCARE, CL_BKNOCARE, CL_BKNOCARE, (UINT)bmp->lpBitmapName, 0, 0);
BitBlt(hdc, StrRect.left, StrRect.top, StrRect.right-StrRect.left, StrRect.bottom-StrRect.top, hMemDC, 1,0,SRCCOPY);
DelMemoryDC(hMemDC, hOldBmp);
if((StrRect.bottom<CNSL_BOX_UPPERTOP+6*(CNSL_BOX_HIGH+3)+CNSL_BOX_AUDIO_HIGH-10)&&(g_UiCoreState!=UI_CORE_STOP))
{
TempRect.left=StrRect.left;
TempRect.top=StrRect.bottom+1;
TempRect.right=StrRect.right-2;
TempRect.bottom=StrRect.bottom+3;
GUI_CreateButtonControl(hdc,&TempRect,clWrite,clWrite,clWrite,clText ,"",UNICODE_STRING, 0, 0);
}
}
#endif
#if 0
//030807-02lily:for stop show just one item
void SetCnslFirstBoxRect(void)
{
BYTE boxhigh;
BYTE bmp_xoffset,bmp_yoffset;
switch(DiscType){
case C_DVD:
case C_DVD_VR:
brc[0].rect.top=CNSL_BOX_UPPERTOP;
brc[0].rect.right=CNSL_BOX_UPPERLEFT+CNSL_BOX_WIDTH;
brc[0].rect.bottom=CNSL_BOX_UPPERTOP+CNSL_BOX_HIGH;
brc[0].bkColor=CNSL_BOX_BACKCOLOR_NORMAL;
brc[0].strColor=CNSL_BOX_STRCOLOR_NORMAL;
bmp_xoffset=CNSL_BOX_BMP_XOFFSET;
bmp_yoffset=((brc[0].rect.bottom-brc[0].rect.top)-CNSL_BOX_BMP_HEIGHT)/2;
bmpbox[0].height=CNSL_BOX_BMP_HEIGHT;
bmpbox[0].width=CNSL_BOX_BMP_WIDTH;
bmpbox[0].upperleftx=brc[0].rect.left+bmp_xoffset;
bmpbox[0].upperlefty=brc[0].rect.top+bmp_yoffset;
bmpbox[0].lpBitmapName=GET_IMNAME(CnslMapGuiId(0));
cnsl_cur_item=0;
break;
case C_DVD_AUDIO:
break;
default:
vcdbrc[0].rect.left=CNSL_BOX_UPPERLEFT;
vcdbrc[0].rect.top=CNSL_BOX_UPPERTOP;
vcdbrc[0].rect.right=CNSL_BOX_UPPERLEFT+CNSL_BOX_WIDTH;
vcdbrc[0].rect.bottom=CNSL_BOX_UPPERTOP+CNSL_BOX_HIGH;
vcdbrc[0].bkColor=CNSL_BOX_BACKCOLOR_NORMAL;
vcdbrc[0].strColor=CNSL_BOX_STRCOLOR_NORMAL;
bmp_xoffset=CNSL_BOX_BMP_XOFFSET;
bmp_yoffset=((vcdbrc[0].rect.bottom-vcdbrc[0].rect.top)-CNSL_BOX_BMP_HEIGHT)/2;// centering the bmp.
vcdbmpbox[0].height=CNSL_BOX_BMP_HEIGHT;
vcdbmpbox[0].width=CNSL_BOX_BMP_WIDTH;
vcdbmpbox[0].upperleftx=vcdbrc[0].rect.left+bmp_xoffset;
vcdbmpbox[0].upperlefty=vcdbrc[0].rect.top+bmp_yoffset;
vcdbmpbox[0].lpBitmapName=GET_IMNAME(CnslMapGuiId(CNSL_BOX_TITLE_VCD));
cnsl_cur_item=0;
break;
}
/*
if(DiscType==C_DVD||DiscType==C_DVD_VR)
{
brc[0].rect.left=CNSL_BOX_UPPERLEFT;
brc[0].rect.top=CNSL_BOX_UPPERTOP;
brc[0].rect.right=CNSL_BOX_UPPERLEFT+CNSL_BOX_WIDTH;
brc[0].rect.bottom=CNSL_BOX_UPPERTOP+CNSL_BOX_HIGH;
brc[0].bkColor=CNSL_BOX_BACKCOLOR_NORMAL;
brc[0].strColor=CNSL_BOX_STRCOLOR_NORMAL;
bmp_xoffset=CNSL_BOX_BMP_XOFFSET;
bmp_yoffset=((brc[0].rect.bottom-brc[0].rect.top)-CNSL_BOX_BMP_HEIGHT)/2;
bmpbox[0].height=CNSL_BOX_BMP_HEIGHT;
bmpbox[0].width=CNSL_BOX_BMP_WIDTH;
bmpbox[0].upperleftx=brc[0].rect.left+bmp_xoffset;
bmpbox[0].upperlefty=brc[0].rect.top+bmp_yoffset;
bmpbox[0].lpBitmapName=GET_IMNAME(CnslMapGuiId(0));
cnsl_cur_item=0;
}
else
{
if(DiscType==C_DVD_AUDIO)
{
}
else
{
vcdbrc[0].rect.left=CNSL_BOX_UPPERLEFT;
vcdbrc[0].rect.top=CNSL_BOX_UPPERTOP;
vcdbrc[0].rect.right=CNSL_BOX_UPPERLEFT+CNSL_BOX_WIDTH;
vcdbrc[0].rect.bottom=CNSL_BOX_UPPERTOP+CNSL_BOX_HIGH;
vcdbrc[0].bkColor=CNSL_BOX_BACKCOLOR_NORMAL;
vcdbrc[0].strColor=CNSL_BOX_STRCOLOR_NORMAL;
bmp_xoffset=CNSL_BOX_BMP_XOFFSET;
bmp_yoffset=((vcdbrc[0].rect.bottom-vcdbrc[0].rect.top)-CNSL_BOX_BMP_HEIGHT)/2;// centering the bmp.
vcdbmpbox[0].height=CNSL_BOX_BMP_HEIGHT;
vcdbmpbox[0].width=CNSL_BOX_BMP_WIDTH;
vcdbmpbox[0].upperleftx=vcdbrc[0].rect.left+bmp_xoffset;
vcdbmpbox[0].upperlefty=vcdbrc[0].rect.top+bmp_yoffset;
vcdbmpbox[0].lpBitmapName=GET_IMNAME(CnslMapGuiId(CNSL_BOX_TITLE_VCD));
vcdcnsl_cur_item=0;
}
}
*/
}
//end 030807-02lily:for stop show just one item
#endif
#if 0
/*----------------------------------------------------------------------------
* Function name: CnslMapGuiId
* Arguments: none
* Return value: None
* Remark: set each item bmp in the console.
comment by chena: get image index for menuitem
boxindex : menuitem
*----------------------------------------------------------------------------*/
WORD CnslMapGuiId(BYTE boxIndex)
{
switch(boxIndex)
{
case CNSL_BOX_TITLE_DVD:
case CNSL_BOX_TITLE_VCD:
return IM_GUI_TITLE;
case CNSL_BOX_CHAPTER_DVD:
return IM_GUI_CHAPTER;
case CNSL_BOX_TIME_DVD:
case CNSL_BOX_TIME_VCD:
return IM_GUI_TIME;
case CNSL_BOX_AUDIO_DVD:
return IM_GUI_AUDIO;
case CNSL_BOX_AUDIO_VCD:
return IM_GUI_ANGLE;
case CNSL_BOX_SUBTITLE_DVD:
return IM_GUI_SUBTITLE;
case CNSL_BOX_ANGLE_DVD:
return IM_GUI_ANGLE;
case CNSL_BOX_SOUND_DVD:
case CNSL_BOX_SOUND_VCD:
return IM_GUI_SOUND;
}
}
#endif
#if 0
//dong qi add this for New UI
//get HighLight Bmp Index
WORD CnslMapGuiId_HighLight(BYTE boxIndex)
{
return(CnslMapGuiId(boxIndex));
}
#endif
#define CnslMapGuiId_HighLight(boxIndex) CnslMapGuiId(boxIndex)
/*----------------------------------------------------------------------------
* Function name: CONSOLEHighLightItem
* Arguments: HDC hdc,BYTE item,BOOL highlight
* Return value: None
* Remark: process highlight moving in console menu.
comment by chena:
item is index
*----------------------------------------------------------------------------*/
void CONSOLEHighLightItem(HDC hdc,BYTE item,BOOL highlight)
{
BYTE str[30];
BYTE j;
if(item == INVALID_ITEM_SELECTION)
return;
#if 0
if(highlight)
{
menus[item].baseRect.bkColor=CNSL_BOX_BACKCOLOR_HIGHLIGHT;
menus[item].baseRect.strColor=CNSL_BOX_STRCOLOR_HIGHLIGHT;
menus[item].baseBmp.lpBitmapName=GET_IMNAME(CnslMapGuiId_HighLight(j));
}
else
{
menus[item].baseRect.bkColor=CNSL_BOX_BACKCOLOR_NORMAL;
menus[item].baseRect.strColor=CNSL_BOX_STRCOLOR_NORMAL;
menus[item].baseBmp.lpBitmapName=GET_IMNAME(CnslMapGuiId(j));
}
#else
menus[item].baseRect.bkColor = highlight?CNSL_BOX_BACKCOLOR_HIGHLIGHT : CNSL_BOX_BACKCOLOR_NORMAL;
menus[item].baseRect.strColor = highlight?CNSL_BOX_STRCOLOR_HIGHLIGHT : CNSL_BOX_STRCOLOR_NORMAL;
// menus[item].baseBmp.lpBitmapName = GET_IMNAME(CnslMapGuiId(j));
#endif
// item+=j;//vcd item first index is CNSL_BOX_TITLE_VCD
if(menus[item].ID==CNSL_BOX_AUDIO_DVD||menus[item].ID==CNSL_BOX_AUDIO_VCD)
{
if((DiscType==C_DVD)||(DiscType==C_DVD_VR))
{
consoleAudioItem.lpbaseRect->rect.left = menus[3].baseRect.rect.left;
consoleAudioItem.lpbaseRect->rect.top = menus[3].baseRect.rect.top;
consoleAudioItem.lpbaseRect->bkColor = CNSL_BOX_BACKCOLOR_NORMAL;
consoleAudioItem.lpbaseRect->strColor = CNSL_BOX_STRCOLOR_NORMAL;
consoleAudioItem.curLine = CheckIfActive(menus[item].ID);
GetAudioInfo2Item(&consoleAudioItem);
if(highlight)
{
consoleAudioItem.lpbaseBmp->lpBitmapName = (LPCTSTR)IM_GUI_AUDIO;
consoleAudioItem.lpbaseRect->bkColor = CNSL_BOX_BACKCOLOR_HIGHLIGHT;
consoleAudioItem.lpbaseRect->strColor = CNSL_BOX_STRCOLOR_HIGHLIGHT;
}
DrawMultiLineCSItem(gui_hdc,&consoleAudioItem);
}
else
{
UINT uID;
if(bVocalPressCnt==C_VOCAL_STEREO) uID = RS_GUI_STEREO;
else if(bVocalPressCnt==C_VOCAL_LEFT) uID = RS_GUI_LEFT;
else if(bVocalPressCnt==C_VOCAL_RIGHT) uID = RS_GUI_RIGHT;
LoadText(uID, str, 30);
ShowBoxWithMemdc(gui_hdc,&menus[2],str,CheckIfActive(cnsl_item_id(item)));
#if 0
LoadText(RS_GUI_STEREO, str,30);
else if(bVocalPressCnt==C_VOCAL_LEFT)
LoadText(RS_GUI_LEFT, str, 30);
else if(bVocalPressCnt==C_VOCAL_RIGHT)
LoadText(RS_GUI_RIGHT, str, 30);
ShowBoxWithMemdc(gui_hdc,&menus[2],str,CheckIfActive(item));
#endif
}
}
else
{
ShowConsleItem(hdc,cnsl_item_id(item));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -