📄 uilistbox.c
字号:
/**************************************************************
INCLUDE FILE
***************************************************************/
#include <pr2k.h>
#include <uiwnd.h>
#include <uiscroll.h>
#include <uiListbox.h>
#include <uiGraph.h>
#include <keypad.h>
/**************************************************************
DATA STRUCTURE
**************************************************************/
/*
typedef struct tagListboxItem
{
char szCaption[LISTBOX_ITEM_LENGTH+1] ; // include NULL character
short nStatus ; //selected or no selected
BYTE *icon; // icon image
}TListboxItem;
typedef struct tagListbox
{
TGuiControl base ;
DList *pItemList ; // head of item list
// property
short nItemCount ; // count of items
short nOffset ; // first visible item
short nSelectedCount ; // count of selected items
short nLastHited; //last hited item
short nLastSelected; // last selected item
short nSecondSelect;
WORD wGap ; // item height
HNDL hVScroll ; // scroll bar in listbox
short a_nColumn_Start[LISTBOX_MAX_COLUMN]; //this array for column start address
}TListbox;
*/
typedef struct tagPopList
{
HNDL handle;
HNDL container;
WORD top,bottom;
WORD left,right;
BYTE * img_buf;
}TPOPLIST;
TPOPLIST POPUP={0,0,0,0,0,0,0};
#define LEFT_BLANK_BORDER 3
#define TOP_BLANK_BORDER 2
#define RIGHT_BLANK_BORDER 12
#define BOTTOM_BLANK_BORDER 2
#define LEFT_BLANK_NONE_BORDER 0
#define TOP_BLANK_NONE_BORDER 0
#define RIGHT_BLANK_NONE_BORDER 9
#define BOTTOM_BLANK_NONE_BORDER 0
int _guiListbox_DrawItem(TListbox * pListbox,WORD start,WORD end);
int _guiListbox_Paint(TListbox * pListbox,WORD start);
int _guiListbox_ShowString(HNDL hListbox,char *str,int x,int y);
DLL_EXP(WORD) guiTextField_LostFocus(void);
static void guiShowStringEx(HNDL handle, const char *szText,int x,int y,int ext, int complex_color, int style);
void _guiListbox_Action(DWORD handle,WORD actionType,WORD x,WORD y)
{
short top,left,bottom,right,gap,index,nOffset,n;
short topBlank,leftBlank,bottomBlank,rightBlank;
// short nSavedSelected=-1;
HNDL hListbox;
TListbox *pListbox;
TGUISCROLL *pScroll;
TGuiMessage tMessage;
hListbox=(HNDL)handle;
pListbox=(TListbox *)handle;
pScroll=(TGUISCROLL *)pListbox->hVScroll;
//check flag
if(pListbox->base.checkFlag!=GUI_CONTROL_CHECK_FLAG)
{
return;
}
if( pListbox->base.status & CONTROL_NOT_ACTIVE)
{
return;
}
// nSavedSelected=pListbox->nLastSelected;
if((pListbox->base.style&LISTBOX_NONE_BORDER)==0)
{
leftBlank=LEFT_BLANK_BORDER;
topBlank=TOP_BLANK_BORDER;
rightBlank=RIGHT_BLANK_BORDER;
bottomBlank=BOTTOM_BLANK_BORDER;
}
else
{
leftBlank=LEFT_BLANK_NONE_BORDER;
topBlank=TOP_BLANK_NONE_BORDER;
rightBlank=RIGHT_BLANK_NONE_BORDER;
bottomBlank=BOTTOM_BLANK_NONE_BORDER;
}
gap=pListbox->wGap;
//translate Coordinate
top=pListbox->base.top;
left=pListbox->base.left;
bottom=pListbox->base.bottom;
right=pListbox->base.right;
if(guiControl_QueryIsActive(handle)==FALSE)
{
return;
}
//deal hardkey
if(actionType==KEYPAD_CLICK)
{
switch(x)
{
case HARDKEY_UP:
if(pListbox->hVScroll)
{
n=guiScroll_GetPos(pListbox->hVScroll);
if(n>0)
{
guiScroll_SetPos(pListbox->hVScroll,(WORD)(n-1));
n=guiScroll_GetPos(pListbox->hVScroll);
if(pListbox->nOffset!=n)
{
pListbox->nOffset=n;
_guiListbox_Paint(pListbox ,pListbox->nOffset);
}
}
}
break;
case HARDKEY_DOWN:
if(pListbox->hVScroll)
{
n=guiScroll_GetPos(pListbox->hVScroll);
if(n>=0)
{
guiScroll_SetPos(pListbox->hVScroll,(WORD)(n+1));
n=guiScroll_GetPos(pListbox->hVScroll);
if(pListbox->nOffset!=n)
{
pListbox->nOffset=n;
_guiListbox_Paint(pListbox ,pListbox->nOffset);
}
}
}
break;
default:
break;
}
return;
}
//deal scrollbar
if(x<=right&&x>=right-_SCROLLBAR_WIDTH_&&y>=top+1&&y<=bottom-1)
{
pScroll->base.actionFun((HNDL)pScroll,actionType,x,y);
nOffset=guiScroll_GetPos((HNDL)pScroll);
if(pListbox->nOffset!=nOffset)
{
pListbox->nOffset=nOffset;
_guiListbox_Paint(pListbox ,pListbox->nOffset);
}
return;
}
//deal selecting or deselecting
if(x>=left&&x<=right&&y>=top+topBlank&&y<=bottom-bottomBlank-((bottom-bottomBlank)-(top+topBlank)+1)%pListbox->wGap)
{
index=(y-top-topBlank)/gap+pListbox->nOffset;
if(actionType==PENDOWN||actionType==PENMOVE)
{
if(pListbox->base.style&LISTBOX_MULTI_SELECT)
{
if(guiListbox_IsSelected(hListbox,index))
{
if(actionType!=PENMOVE||index!=pListbox->nLastHited&&!guiListbox_IsSelected(hListbox,pListbox->nLastHited))
{
guiListbox_Deselect(hListbox,index);
}
}
else
{
if(actionType!=PENMOVE||index!=pListbox->nLastHited&&guiListbox_IsSelected(hListbox,pListbox->nLastHited))
{
guiListbox_Select(hListbox,index);
}
}
}
else
{
if(!guiListbox_IsSelected(hListbox,index))
{
if(index<pListbox->nItemCount) // by zhangxp
{
guiListbox_Deselect(hListbox,pListbox->nLastHited);
guiListbox_Select(hListbox,index);
}
}
else
{
if(actionType==PENDOWN)
{
guiListbox_Select(hListbox,index);
}
if(actionType!=PENMOVE||index!=pListbox->nLastHited)
{
// guiListbox_Deselect(hListbox,pListbox->nLastHited);
}
}
}
}
if(actionType==PENUP&&index<pListbox->nItemCount)
{
tMessage.handle=hListbox;
tMessage.x=index;
tMessage.y=pListbox->nSecondSelect;
if(tMessage.y)
{
tMessage.messageType=LISTBOX_CLICK;
}
tMessage.messageType=LISTBOX_CLICK;
guiEnqueue(gpTopWindow->messageQueue,&tMessage);
guiPenSound();
}
}
else if((pListbox->base.style&LISTBOX_MULTI_SELECT)==0)
{
// hit blank region, don't process by zhangxp 2003/06/10
/*
if(pListbox->nLastHited!=-1)
{
guiListbox_Deselect(hListbox, pListbox->nLastHited);
pListbox->nLastHited=-1;
pListbox->nSecondSelect=0;
}
*/
}
return;
}
int _guiListbox_Paint(TListbox * pListbox,WORD start)
{
int top,left,bottom,right;
HNDL hListbox,hBoard;
TGUISCROLL *pScroll;
hListbox=(HNDL)pListbox;
pScroll=(TGUISCROLL *)pListbox->hVScroll;
if(pListbox->base.checkFlag!=GUI_CONTROL_CHECK_FLAG)
{
return STATUS_ERR;
}
if(!guiControl_IsVisible(hListbox))
{
return STATUS_ERR;
}
if(pListbox->base.container!=NULL)
{
pScroll->base.container=pListbox->base.container;
}
else if(pListbox->base.vportHandle!=NULL)
{
pScroll->base.vportHandle=pListbox->base.vportHandle;
}
top=0;
left=0;
right=pListbox->base.right-pListbox->base.left;
bottom=pListbox->base.bottom-pListbox->base.top;
if(pListbox->base.style&LISTBOX_POPUP)
{
_guiConvertXY(hListbox,&left,&top);
_guiConvertXY(hListbox,&right,&bottom);
hBoard=0;
}
else
{
hBoard=hListbox;
}
// guiEnterWCS();
// guiClearBlock(hListbox,left,top,right,bottom,GUI_WHITE,REPLACE_STYLE);
if((pListbox->base.style&LISTBOX_NONE_BORDER)==0)
{
guiDrawLine(hBoard,left,top,right,top,GUI_BLACK,GUI_SOLID);
guiDrawLine(hBoard,left,top,left,bottom,GUI_BLACK,GUI_SOLID);
guiDrawLine(hBoard,left,bottom,right,bottom,GUI_BLACK,GUI_SOLID);
guiDrawLine(hBoard,right,top,right,bottom,GUI_BLACK,GUI_SOLID);
}
if(start<pListbox->nOffset)
{
pListbox->nOffset=start;
}
//deal scrollbar
pScroll->base.left=pListbox->base.right-_SCROLLBAR_WIDTH_;
pScroll->base.top=pListbox->base.top+1;
pScroll->base.right=pListbox->base.right-1;
pScroll->base.bottom=pListbox->base.bottom-1;
guiScroll_Update((HNDL)pScroll,pListbox->nItemCount,(bottom-top-4)/pListbox->wGap,pListbox->nOffset);
if(pListbox->nItemCount>0)
{
_guiListbox_DrawItem(pListbox,start,pListbox->nItemCount-1);
}
else
{
guiClearBlock(hBoard,left+1,top+1,right-1,bottom-1,GUI_WHITE,GUI_SOLID);
}
// guiExitWCS();
return STATUS_OK;
}
int _guiListbox_DrawItem(TListbox * pListbox,WORD start,WORD end)
{
int iStart,iStringHeight,iOffset_Y;
WORD i,index,wSumLine;
int top,left,bottom,right,gap;
WORD topBlank,leftBlank,bottomBlank,rightBlank;
HNDL hListbox,hBoard;
TListboxItem *pItem;
hListbox = (HNDL)pListbox;
if(pListbox->base.status&CONTROL_NOT_VISIBLE)
{
return STATUS_ERR;
}
if((pListbox->base.style&LISTBOX_NONE_BORDER)==0)
{
leftBlank=LEFT_BLANK_BORDER;
topBlank=TOP_BLANK_BORDER;
rightBlank=RIGHT_BLANK_BORDER;
bottomBlank=BOTTOM_BLANK_BORDER;
}
else
{
leftBlank=LEFT_BLANK_NONE_BORDER;
topBlank=TOP_BLANK_NONE_BORDER;
rightBlank=RIGHT_BLANK_NONE_BORDER;
bottomBlank=BOTTOM_BLANK_NONE_BORDER;
}
gap=pListbox->wGap;
top=0;
bottom=pListbox->base.bottom-pListbox->base.top;
left=0;
right=pListbox->base.right-pListbox->base.left;
if(pListbox->base.style&LISTBOX_POPUP)
{
_guiConvertXY(hListbox,&left,&top);
_guiConvertXY(hListbox,&right,&bottom);
hBoard=0;
}
else
{
hBoard=hListbox;
}
wSumLine=(bottom-top-4)/gap;
guiPushFont(GUI_DEFAULT_FONT);
for(i=0;i<wSumLine;i++)
{
index=pListbox->nOffset+i;
if(!(index>=start&&index<=end))
{
if(index>pListbox->nItemCount-1)
{
guiClearBlock(hBoard,left+leftBlank,top+i*gap+topBlank,right-rightBlank,top+topBlank+(i+1)*gap-1,GUI_WHITE,REPLACE_STYLE);
}
continue;
}
pItem=(TListboxItem *)DList_GetObject(pListbox->pItemList,index);
guiClearBlock(hBoard,left+leftBlank,top+i*gap+topBlank,right-rightBlank,top+topBlank+(i+1)*gap-1,GUI_WHITE,REPLACE_STYLE);
//draw icon and show string
if(pListbox->base.style&LISTBOX_ENABLE_ICON)
{
if(pItem->icon!=NULL)
{
guiPutImage(hBoard,left+leftBlank,top+topBlank+i*gap+1,left+leftBlank+LISTBOX_ICON_SIZE-1,top+topBlank+i*gap+LISTBOX_ICON_SIZE,pItem->icon);
}
iStart=left+leftBlank+LISTBOX_ICON_SIZE;
}
else
{
iStart=left+leftBlank;
}
iStringHeight=guiGetStringHeight();
iOffset_Y=iStringHeight>=gap?0:(gap-iStringHeight)/2;
_guiListbox_ShowString(hListbox,pItem->szCaption,iStart,top+topBlank+i*gap+iOffset_Y);
if(pItem->nStatus==ITEM_SELECTED)
{
guiInvertRect(hBoard,left+leftBlank,top+topBlank+i*gap,right-rightBlank,top+topBlank+(i+1)*gap-1);
}
}
guiPopFont();
return STATUS_OK;
}
/* create a listbox */
DLL_EXP(HNDL) guiListbox_Create( WORD left, WORD top, WORD right, WORD bottom, WORD gap, WORD style)
{
WORD topBlank,bottomBlank;
TListbox *pListbox;
DList *pDList;
//allocate space
pListbox=(TListbox *)sc_malloc(sizeof(TListbox));
if(pListbox==NULL)
{
return 0;
}
pDList=DList_Create();
if(pDList==NULL)
{
sc_free(pListbox);
return 0;
}
if((pListbox->base.style&LISTBOX_NONE_BORDER)==0)
{
topBlank=TOP_BLANK_BORDER;
bottomBlank=BOTTOM_BLANK_BORDER;
}
else
{
topBlank=TOP_BLANK_NONE_BORDER;
bottomBlank=BOTTOM_BLANK_NONE_BORDER;
}
//initialize value
memset(pListbox,0,sizeof(TListbox));
pListbox->base.type=CONTROL_LISTBOX;
pListbox->base.handle=(HNDL)pListbox;
pListbox->base.checkFlag=GUI_CONTROL_CHECK_FLAG;
if(style&LISTBOX_POPUP)
{
pListbox->base.status=CONTROL_NOT_ACTIVE|CONTROL_NOT_VISIBLE;
}
else
{
pListbox->base.status=0;
}
pListbox->base.actionFun=_guiListbox_Action;
pListbox->base.showFun=guiListbox_Show;
pListbox->base.delFun=guiListbox_Delete;
pListbox->base.font=GUI_DEFAULT_FONT;
pListbox->base.top=top;
pListbox->base.bottom=bottom;
pListbox->base.left=left;
pListbox->base.right=right;
pListbox->base.style=style;
pListbox->nOffset=0;
pListbox->nSecondSelect=0;
pListbox->nLastHited=-1;
pListbox->nLastSelected=-1;
pListbox->pItemList=pDList;
pListbox->a_nColumn_Start[0]=0;
pListbox->a_nColumn_Start[1]=-1;
pListbox->wGap=gap<LISTBOX_DEFAULT_GAP?LISTBOX_DEFAULT_GAP:gap;
if(pListbox->base.style & LISTBOX_POPUP)
pListbox->hVScroll=guiScroll_Create(right-_SCROLLBAR_WIDTH_,top+1,bottom-1,((bottom-bottomBlank)-(top+topBlank))/pListbox->wGap,0,SCROLL_POPUP);
else
pListbox->hVScroll=guiScroll_Create(right-_SCROLLBAR_WIDTH_,top+1,bottom-1,((bottom-bottomBlank)-(top+topBlank))/pListbox->wGap,0,0);
return (HNDL)pListbox;
}
/* delete a listbox */
DLL_EXP(int) guiListbox_Delete( HNDL hListbox )
{
HNDL hScroll;
TListbox *pListbox;
pListbox=(TListbox *)hListbox;
hScroll=pListbox->hVScroll;
guiEnterWCS();
if(pListbox->base.checkFlag!=GUI_CONTROL_CHECK_FLAG)
{
guiExitWCS();
return STATUS_ERR;
}
DList_Delete(pListbox->pItemList);
pListbox->base.checkFlag=0;
kernelFree(pListbox);
guiControl_Delete(hScroll);
guiExitWCS();
return STATUS_OK;
}
/* enable a listbox */
DLL_EXP(int) guiListbox_Show( HNDL hListbox )
{
TListbox * pListbox;
pListbox=(TListbox *)hListbox;
guiEnterWCS();
_guiListbox_Paint(pListbox,pListbox->nOffset);
guiExitWCS();
return STATUS_OK;
}
/* append listbox item */
DLL_EXP(int) guiListbox_AddItem( HNDL hListbox, const char *string)
{
TListbox * pListbox;
pListbox=(TListbox *)hListbox;
return guiListbox_InsertItem(hListbox,pListbox->nItemCount,string);
}
/* insert listbox item */
DLL_EXP(int) guiListbox_InsertItem( HNDL hListbox, WORD index, const char *string)
{
WORD wSumLine;
TListboxItem * pItem;
TListbox * pListbox;
pListbox=(TListbox *)hListbox;
guiEnterWCS();
pItem=(TListboxItem *)sc_malloc(sizeof(TListboxItem));
if(pItem==NULL)
{
guiExitWCS();
return STATUS_ERR;
}
memset(pItem,0,sizeof(TListboxItem));
strncpy(pItem->szCaption,string,LISTBOX_ITEM_LENGTH-1);
pItem->szCaption[LISTBOX_ITEM_LENGTH-1]=0;
if(index>pListbox->nItemCount-1)
{
DList_Append(pListbox->pItemList,pItem);
}
else
{
DList_Insert(pListbox->pItemList,index,pItem);
}
pListbox->nItemCount++;
if(pListbox->nLastHited>=index)
{
pListbox->nLastHited++;
}
if(pListbox->nLastSelected>=index)
{
pListbox->nLastSelected++;
}
_guiListbox_Paint(pListbox,index);
guiExitWCS();
return STATUS_OK;
}
/* remove listbox item */
DLL_EXP(int) guiListbox_RemoveItem( HNDL hListbox, WORD index)
{
TListboxItem * pItem;
TListbox * pListbox;
pListbox=(TListbox *)hListbox;
guiEnterWCS();
if(pListbox->base.checkFlag!=GUI_CONTROL_CHECK_FLAG)
{
guiExitWCS();
return STATUS_ERR;
}
if(index>=pListbox->nItemCount)
{
guiExitWCS();
return STATUS_ERR;
}
pItem=(TListboxItem *)DList_Remove(pListbox->pItemList,index);
if(pListbox->nOffset>0&&pListbox->nOffset==index&&pListbox->nItemCount==index+1)
{
pListbox->nOffset--;
}
pListbox->nItemCount--;
if(pItem->nStatus==ITEM_SELECTED)
{
if(pListbox->base.style&LISTBOX_MULTI_SELECT==1)
{
pListbox->nSelectedCount--;
}
if(pListbox->nLastHited==index)
{
pListbox->nLastHited=-1;
}
if(pListbox->nLastSelected==index)
{
pListbox->nLastSelected=-1;
}
}
sc_free(pItem);
_guiListbox_Paint(pListbox,pListbox->nOffset);
guiExitWCS();
return STATUS_OK;
}
/* remove all listbox items */
DLL_EXP(int) guiListbox_RemoveAll( HNDL hListbox )
{
WORD i;
WORD left,top,right,bottom;
void * pItem;
TListbox * pListbox;
pListbox=(TListbox *)hListbox;
guiEnterWCS();
if(pListbox->base.checkFlag!=GUI_CONTROL_CHECK_FLAG)
{
guiExitWCS();
return STATUS_ERR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -