📄 listbox.c
字号:
pItem->xSize = 0;
pItem->ySize = 0;
}
}
/*********************************************************************
*
* LISTBOX__InvalidateInsideArea
*/
void LISTBOX__InvalidateInsideArea(LISTBOX_Handle hObj) {
GUI_RECT Rect;
WM_GetInsideRectExScrollbar(hObj, &Rect);
WM_InvalidateRect(hObj, &Rect);
}
/*********************************************************************
*
* LISTBOX__InvalidateItem
*/
void LISTBOX__InvalidateItem(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj, int Sel) {
if (Sel >= 0) {
int ItemPosY;
ItemPosY = _GetItemPosY(hObj, pObj, Sel);
if (ItemPosY >= 0) {
GUI_RECT Rect;
int ItemDistY;
ItemDistY = _GetItemSizeY(hObj, pObj, Sel);
WM_GetInsideRectExScrollbar(hObj, &Rect);
Rect.y0 += ItemPosY;
Rect.y1 = Rect.y0 + ItemDistY - 1;
WM_InvalidateRect(hObj, &Rect);
}
}
}
/*********************************************************************
*
* LISTBOX__InvalidateItemAndBelow
*/
void LISTBOX__InvalidateItemAndBelow(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj, int Sel) {
if (Sel >= 0) {
int ItemPosY;
ItemPosY = _GetItemPosY(hObj, pObj, Sel);
if (ItemPosY >= 0) {
GUI_RECT Rect;
WM_GetInsideRectExScrollbar(hObj, &Rect);
Rect.y0 += ItemPosY;
WM_InvalidateRect(hObj, &Rect);
}
}
}
/*********************************************************************
*
* LISTBOX__SetScrollbarWidth
*/
void LISTBOX__SetScrollbarWidth(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj) {
WM_HWIN hBarH, hBarV;
int Width;
Width = pObj->ScrollbarWidth;
if (Width == 0) {
Width = SCROLLBAR_GetDefaultWidth();
}
hBarH = WM_GetDialogItem(hObj, GUI_ID_HSCROLL);
hBarV = WM_GetDialogItem(hObj, GUI_ID_VSCROLL);
SCROLLBAR_SetWidth(hBarH, Width);
SCROLLBAR_SetWidth(hBarV, Width);
}
/*********************************************************************
*
* LISTBOX__SetScrollbarColor
*/
void LISTBOX__SetScrollbarColor(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj) {
WM_HWIN hBarH, hBarV;
int i;
hBarH = WM_GetDialogItem(hObj, GUI_ID_HSCROLL);
hBarV = WM_GetDialogItem(hObj, GUI_ID_VSCROLL);
if (hBarH || hBarV) {
for (i = 0; i < GUI_COUNTOF(pObj->Props.aScrollbarColor); i++) {
if (pObj->Props.aScrollbarColor[i] != GUI_INVALID_COLOR) {
SCROLLBAR_SetColor(hBarH, i, pObj->Props.aScrollbarColor[i]);
SCROLLBAR_SetColor(hBarV, i, pObj->Props.aScrollbarColor[i]);
}
}
}
}
/*********************************************************************
*
* Exported routines: Callback
*
**********************************************************************
*/
/*********************************************************************
*
* LISTBOX_Callback
*/
void LISTBOX_Callback(WM_MESSAGE * pMsg) {
LISTBOX_Handle hObj;
LISTBOX_Obj * pObj;
WM_SCROLL_STATE ScrollState;
WM_MESSAGE Msg;
hObj = pMsg->hWin;
pObj = (LISTBOX_Obj *)GUI_ALLOC_h2p(hObj); /* Don't use use WIDGET_H2P because WIDGET_INIT_ID() has not be called at this point */
/* Let widget handle the standard messages */
if (WIDGET_HandleActive(hObj, pMsg) == 0) {
/* Owner needs to be informed about focus change */
if (pMsg->MsgId == WM_SET_FOCUS) {
if (pMsg->Data.v == 0) { /* Lost focus ? */
_NotifyOwner(hObj, LISTBOX_NOTIFICATION_LOST_FOCUS);
}
}
return;
}
switch (pMsg->MsgId) {
case WM_NOTIFY_PARENT:
switch (pMsg->Data.v) {
case WM_NOTIFICATION_VALUE_CHANGED:
if (pMsg->hWinSrc == WM_GetScrollbarV(hObj)) {
WM_GetScrollState(pMsg->hWinSrc, &ScrollState);
pObj->ScrollStateV.v = ScrollState.v;
LISTBOX__InvalidateInsideArea(hObj);
_NotifyOwner(hObj, WM_NOTIFICATION_SCROLL_CHANGED);
} else if (pMsg->hWinSrc == WM_GetScrollbarH(hObj)) {
WM_GetScrollState(pMsg->hWinSrc, &ScrollState);
pObj->ScrollStateH.v = ScrollState.v;
LISTBOX__InvalidateInsideArea(hObj);
_NotifyOwner(hObj, WM_NOTIFICATION_SCROLL_CHANGED);
}
break;
case WM_NOTIFICATION_SCROLLBAR_ADDED:
#if WIDGET_USE_PARENT_EFFECT
WIDGET_SetEffect(pMsg->hWinSrc, pObj->Widget.pEffect);
#endif
LISTBOX_UpdateScrollers(hObj);
break;
}
break;
case WM_PAINT:
_OnPaint(hObj, pObj, pMsg);
break;
case WM_PID_STATE_CHANGED:
{
const WM_PID_STATE_CHANGED_INFO* pInfo = (const WM_PID_STATE_CHANGED_INFO*)pMsg->Data.p;
if (pInfo->State) {
int Sel;
Sel = _GetItemFromPos(hObj, pObj, pInfo->x, pInfo->y);
if (Sel >= 0) {
_ToggleMultiSel(hObj, pObj, Sel);
LISTBOX_SetSel(hObj, Sel);
}
_NotifyOwner(hObj, WM_NOTIFICATION_CLICKED);
return;
}
}
break;
case WM_TOUCH:
_OnTouch(hObj, pMsg);
return;
#if GUI_SUPPORT_MOUSE
case WM_MOUSEOVER:
if (_OnMouseOver(hObj, pObj, pMsg) == 0)
return;
break;
#endif
case WM_DELETE:
_FreeAttached(pObj);
break; /* No return here ... WM_DefaultProc needs to be called */
case WM_KEY:
if (((const WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt > 0) {
int Key;
Key = ((const WM_KEY_INFO*)(pMsg->Data.p))->Key;
if (LISTBOX_AddKey(hObj, Key)) {
return;
}
}
/* Send a WM_NOTIFY_OWNER_KEY message with the key information to the owner window */
Msg = *pMsg;
Msg.MsgId = WM_NOTIFY_OWNER_KEY;
_SendToOwner(hObj, &Msg);
if (!WM_IsWindow(hObj)) {
return;
}
break;
case WM_SIZE:
LISTBOX_UpdateScrollers(hObj);
WM_InvalidateWindow(hObj);
break;
}
WM_DefaultProc(pMsg);
}
/*********************************************************************
*
* Exported routines: Create
*
**********************************************************************
*/
/*********************************************************************
*
* LISTBOX_CreateEx
*/
LISTBOX_Handle LISTBOX_CreateEx(int x0, int y0, int xsize, int ysize, WM_HWIN hParent,
int WinFlags, int ExFlags, int Id, const GUI_ConstString* ppText)
{
LISTBOX_Handle hObj;
GUI_USE_PARA(ExFlags);
WM_LOCK();
hObj = WM_CreateWindowAsChild(x0, y0, xsize, ysize, hParent, WinFlags, LISTBOX_Callback,
sizeof(LISTBOX_Obj) - sizeof(WM_Obj));
if (hObj) {
LISTBOX_Obj* pObj;
pObj = (LISTBOX_Obj *)GUI_ALLOC_h2p(hObj); /* Don't use use WIDGET_H2P because WIDGET_INIT_ID() has not be called at this point */
/* Init sub-classes */
GUI_ARRAY_CREATE(&pObj->ItemArray);
/* init widget specific variables */
WIDGET__Init(&pObj->Widget, Id, WIDGET_STATE_FOCUSSABLE);
LISTBOX_INIT_ID(pObj);
pObj->Props = LISTBOX_DefaultProps;
if (ppText) {
/* init member variables */
/* Set non-zero attributes */
LISTBOX_SetText(hObj, ppText);
}
LISTBOX_UpdateScrollers(hObj);
}
WM_UNLOCK();
return hObj;
}
/*********************************************************************
*
* Exported routines: Various methods
*
**********************************************************************
*/
/*********************************************************************
*
* LISTBOX_InvalidateItem
*/
void LISTBOX_InvalidateItem(LISTBOX_Handle hObj, int Index) {
if (hObj) {
LISTBOX_Obj* pObj;
int NumItems;
WM_LOCK();
pObj = LISTBOX_H2P(hObj);
NumItems = LISTBOX__GetNumItems(pObj);
if (Index < NumItems) {
if (Index < 0) {
int i;
for (i = 0; i < NumItems; i++) {
LISTBOX__InvalidateItemSize(pObj, i);
}
LISTBOX_UpdateScrollers(hObj);
LISTBOX__InvalidateInsideArea(hObj);
} else {
LISTBOX__InvalidateItemSize(pObj, Index);
LISTBOX_UpdateScrollers(hObj);
LISTBOX__InvalidateItemAndBelow(hObj, pObj, Index);
}
}
WM_UNLOCK();
}
}
/*********************************************************************
*
* LISTBOX_AddKey
*
* Returns: 1 if Key has been consumed
* 0 else
*/
int LISTBOX_AddKey(LISTBOX_Handle hObj, int Key) {
int r = 0;
if (hObj) {
WM_LOCK();
r = _AddKey(hObj, Key);
WM_UNLOCK();
}
return r;
}
/*********************************************************************
*
* LISTBOX_AddString
*/
void LISTBOX_AddString(LISTBOX_Handle hObj, const char* s) {
if (hObj && s) {
LISTBOX_Obj* pObj;
LISTBOX_ITEM Item = {0, 0};
WM_LOCK();
pObj = LISTBOX_H2P(hObj);
if (GUI_ARRAY_AddItem(&pObj->ItemArray, &Item, sizeof(LISTBOX_ITEM) + strlen(s)) == 0) {
unsigned ItemIndex = GUI_ARRAY_GetNumItems(&pObj->ItemArray) - 1;
LISTBOX_ITEM* pItem= (LISTBOX_ITEM*)GUI_ARRAY_GetpItem(&pObj->ItemArray, ItemIndex);
strcpy(pItem->acText, s);
LISTBOX__InvalidateItemSize(pObj, ItemIndex);
LISTBOX_UpdateScrollers(hObj);
LISTBOX__InvalidateItem(hObj, pObj, ItemIndex);
}
WM_UNLOCK();
}
}
/*********************************************************************
*
* LISTBOX_SetText
*/
void LISTBOX_SetText(LISTBOX_Handle hObj, const GUI_ConstString* ppText) {
if (hObj) {
int i;
const char* s;
WM_LOCK();
if (ppText) {
for (i = 0; (s = *(ppText+i)) != 0; i++) {
LISTBOX_AddString(hObj, s);
}
}
LISTBOX_InvalidateItem(hObj, LISTBOX_ALL_ITEMS);
WM_UNLOCK();
}
}
/*********************************************************************
*
* LISTBOX_SetSel
*/
void LISTBOX_SetSel (LISTBOX_Handle hObj, int NewSel) {
if (hObj) {
LISTBOX_Obj* pObj;
int MaxSel;
WM_LOCK();
pObj = LISTBOX_H2P(hObj);
MaxSel = LISTBOX__GetNumItems(pObj);
MaxSel = MaxSel ? MaxSel - 1 : 0;
if (NewSel > MaxSel) {
NewSel = MaxSel;
}
if (NewSel < 0) {
NewSel = -1;
} else {
WM_HMEM hItem = GUI_ARRAY_GethItem(&pObj->ItemArray, NewSel);
if (hItem) {
LISTBOX_ITEM* pItem = (LISTBOX_ITEM*)GUI_ALLOC_h2p(hItem);
if (pItem->Status & LISTBOX_ITEM_DISABLED) {
NewSel = -1;
}
}
}
if (NewSel != pObj->Sel) {
int OldSel;
OldSel = pObj->Sel;
pObj->Sel = NewSel;
if (_UpdateScrollPos(hObj, pObj)) {
LISTBOX__InvalidateInsideArea(hObj);
} else {
LISTBOX__InvalidateItem(hObj, pObj, OldSel);
LISTBOX__InvalidateItem(hObj, pObj, NewSel);
}
_NotifyOwner(hObj, WM_NOTIFICATION_SEL_CHANGED);
}
WM_UNLOCK();
}
}
/*********************************************************************
*
* LISTBOX_GetSel
*/
int LISTBOX_GetSel (LISTBOX_Handle hObj) {
int r = -1;
LISTBOX_Obj* pObj;
if (hObj) {
WM_LOCK();
pObj = LISTBOX_H2P(hObj);
r = pObj->Sel;
WM_UNLOCK();
}
return r;
}
/*********************************************************************
*
* LISTBOX_IncSel
*/
void LISTBOX_IncSel (LISTBOX_Handle hObj) {
if (hObj) {
WM_LOCK();
_MoveSel(hObj, 1);
WM_UNLOCK();
}
}
/*********************************************************************
*
* LISTBOX_DecSel
*/
void LISTBOX_DecSel (LISTBOX_Handle hObj) {
if (hObj) {
WM_LOCK();
_MoveSel(hObj, -1);
WM_UNLOCK();
}
}
#else /* Avoid problems with empty object modules */
void LISTBOX_C(void) {}
#endif
/*************************** End of file ****************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -