/********************************************************************* * * LISTBOX_SetItemDisabled */ void LISTBOX_SetItemDisabled(LISTBOX_Handle hObj, unsigned Index, int OnOff) { if (hObj) { unsigned NumItems; LISTBOX_Obj* pObj; WM_LOCK(); pObj = LISTBOX_H2P(hObj); NumItems = LISTBOX__GetNumItems(pObj); if (Index < NumItems) { WM_HMEM hItem = GUI_ARRAY_GethItem(&pObj->ItemArray, Index); if (hItem) { LISTBOX_ITEM * pItem = (LISTBOX_ITEM *)GUI_ALLOC_h2p(hItem); if (OnOff) { if (!(pItem->Status & LISTBOX_ITEM_DISABLED)) { pItem->Status |= LISTBOX_ITEM_DISABLED; LISTBOX__InvalidateItem(hObj, pObj, Index); } } else { if (pItem->Status & LISTBOX_ITEM_DISABLED) { pItem->Status &= ~LISTBOX_ITEM_DISABLED; LISTBOX__InvalidateItem(hObj, pObj, Index); } } } } WM_UNLOCK(); } }
/********************************************************************* * * LISTBOX_GetNumItems */ unsigned LISTBOX_GetNumItems(LISTBOX_Handle hObj) { int r = 0; if (hObj) { LISTBOX_Obj* pObj; WM_LOCK(); pObj = LISTBOX_H2P(hObj); r = LISTBOX__GetNumItems(pObj); WM_UNLOCK(); } return r; }
/********************************************************************* * * _CalcScrollParas */ static int _CalcScrollParas(LISTBOX_Handle hObj) { GUI_RECT Rect; LISTBOX_Obj* pObj = LISTBOX_H2P(hObj); /* Calc vertical scroll parameters */ pObj->ScrollStateV.NumItems = LISTBOX__GetNumItems(pObj); pObj->ScrollStateV.PageSize = _GetNumVisItems(pObj, hObj); /* Calc horizontal scroll parameters */ WM_GetInsideRectExScrollbar(hObj, &Rect); pObj->ScrollStateH.NumItems = _GetContentsSizeX(hObj); pObj->ScrollStateH.PageSize = Rect.x1 - Rect.x0 + 1; return _UpdateScrollPos(hObj, pObj); }
/********************************************************************* * * _SelectByKey */ static void _SelectByKey(LISTBOX_Handle hObj, int Key) { unsigned i; LISTBOX_Obj* pObj; pObj = LISTBOX_H2P(hObj); Key = _Tolower(Key); for (i = 0; i < LISTBOX__GetNumItems(pObj); i++) { const char* s = LISTBOX__GetpString(pObj, i); if (_Tolower(*s) == Key) { LISTBOX_SetSel(hObj, i); break; } } }
/********************************************************************* * * _GetItemPosY */ static int _GetItemPosY(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj, unsigned Index) { if (Index < LISTBOX__GetNumItems(pObj)) { if ((int)Index >= pObj->ScrollStateV.v) { unsigned i; int PosY = 0; for (i = pObj->ScrollStateV.v; i < Index; i++) { PosY += _GetItemSizeY(hObj, pObj, i); } return PosY; } } return -1; }
/********************************************************************* * * _OnPaint */ static void _OnPaint(LISTBOX_Handle hObj, LISTBOX_Obj* pObj, WM_MESSAGE* pMsg) { WIDGET_ITEM_DRAW_INFO ItemInfo; GUI_RECT RectInside, RectItem, ClipRect; int ItemDistY, NumItems, i; NumItems = LISTBOX__GetNumItems(pObj); GUI_SetFont(pObj->Props.pFont); /* Calculate clipping rectangle */ ClipRect = *(const GUI_RECT*)pMsg->Data.p; GUI_MoveRect(&ClipRect, -pObj->Widget.Win.Rect.x0, -pObj->Widget.Win.Rect.y0); WM_GetInsideRectExScrollbar(hObj, &RectInside); GUI__IntersectRect(&ClipRect, &RectInside); RectItem.x0 = ClipRect.x0; RectItem.x1 = ClipRect.x1; /* Fill item info structure */ ItemInfo.Cmd = WIDGET_ITEM_DRAW; ItemInfo.hWin = hObj; ItemInfo.x0 = RectInside.x0 - pObj->ScrollStateH.v; ItemInfo.y0 = RectInside.y0; /* Do the drawing */ for (i = pObj->ScrollStateV.v; i < NumItems; i++) { RectItem.y0 = ItemInfo.y0; /* Break when all other rows are outside the drawing area */ if (RectItem.y0 > ClipRect.y1) { break; } ItemDistY = _GetItemSizeY(hObj, pObj, i); RectItem.y1 = RectItem.y0 + ItemDistY - 1; /* Make sure that we draw only when row is in drawing area */ if (RectItem.y1 >= ClipRect.y0) { /* Set user clip rect */ WM_SetUserClipArea(&RectItem); /* Fill item info structure */ ItemInfo.ItemIndex = i; /* Draw item */ if (pObj->pfDrawItem) { pObj->pfDrawItem(&ItemInfo); } else { LISTBOX_OwnerDraw(&ItemInfo); } } ItemInfo.y0 += ItemDistY; } WM_SetUserClipArea(NULL); /* Calculate & clear 'data free' area */ RectItem.y0 = ItemInfo.y0; RectItem.y1 = RectInside.y1; LCD_SetBkColor(pObj->Props.aBackColor[0]); GUI_ClearRectEx(&RectItem); /* Draw the 3D effect (if configured) */ WIDGET__EFFECT_DrawDown(&pObj->Widget); }
/********************************************************************* * * _GetContentsSizeX */ static int _GetContentsSizeX(LISTBOX_Handle hObj) { LISTBOX_Obj* pObj; int i, NumItems, SizeX; int Result = 0; pObj = LISTBOX_H2P(hObj); NumItems = LISTBOX__GetNumItems(pObj); for (i = 0; i < NumItems; i++) { SizeX = _GetItemSizeX(hObj, pObj, i); if (Result < SizeX) { Result = SizeX; } } return Result; }
/********************************************************************* * * _IsPartiallyVis */ static int _IsPartiallyVis(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj) { int Index; Index = pObj->Sel; if (Index < (int)LISTBOX__GetNumItems(pObj)) { if (Index >= pObj->ScrollStateV.v) { int y; y = _GetItemPosY (hObj, pObj, Index); y += _GetItemSizeY(hObj, pObj, Index); if (y > _GetYSize(hObj)) { return 1; } } } return 0; }
/********************************************************************* * * LISTBOX_SetString */ void LISTBOX_SetString(LISTBOX_Handle hObj, const char* s, unsigned int Index) { if (hObj) { LISTBOX_Obj* pObj; WM_LOCK(); pObj = LISTBOX_H2P(hObj); if (Index < (unsigned int)LISTBOX__GetNumItems(pObj)) { LISTBOX_ITEM* pItem; pItem = (LISTBOX_ITEM*)GUI_ARRAY_ResizeItem(&pObj->ItemArray, Index, sizeof(LISTBOX_ITEM) + strlen(s)); if (pItem) { strcpy(pItem->acText, s); LISTBOX__InvalidateItemSize(pObj, Index); LISTBOX_UpdateScrollers(hObj); LISTBOX__InvalidateItem(hObj, pObj, Index); } } WM_UNLOCK(); } }
/********************************************************************* * * _GetItemFromPos */ static int _GetItemFromPos(LISTBOX_Handle hObj, LISTBOX_Obj* pObj, int x, int y) { int Sel = -1; GUI_RECT Rect; WM_GetInsideRectExScrollbar(hObj, &Rect); if ((x >= Rect.x0) && (y >= Rect.y0)) { if ((x <= Rect.x1) && (y <= Rect.y1)) { int NumItems = LISTBOX__GetNumItems(pObj); int i, y0 = Rect.y0; for (i = pObj->ScrollStateV.v; i < NumItems; i++) { if (y >= y0) { Sel = i; } y0 += _GetItemSizeY(hObj, pObj, i); } } } return Sel; }
/********************************************************************* * * _GetNumVisItems * * Returns: * Number of fully or partially visible items */ static unsigned _GetNumVisItems(const LISTBOX_Obj* pObj, LISTBOX_Handle hObj) { int NumItems, r = 1; NumItems = LISTBOX__GetNumItems(pObj); if (NumItems > 1) { int i, ySize, DistY = 0; ySize = _GetYSize(hObj); for (i = NumItems - 1; i >= 0; i--) { DistY += _GetItemSizeY(hObj, pObj, i); if (DistY > ySize) { break; } } r = NumItems - i - 1; if (r < 1) { return 1; } } return r; }
/********************************************************************* * * _ManageAutoScroll */ static void _ManageAutoScroll(LISTBOX_Handle hObj) { char IsRequired; LISTBOX_Obj* pObj = LISTBOX_H2P(hObj); if (pObj->Flags & LISTBOX_SF_AUTOSCROLLBAR_V) { IsRequired = (_GetNumVisItems(pObj, hObj) < LISTBOX__GetNumItems(pObj)); WM_SetScrollbarV(hObj, IsRequired); } if (pObj->Flags & LISTBOX_SF_AUTOSCROLLBAR_H) { GUI_RECT Rect; int xSize, xSizeContents; xSizeContents = _GetContentsSizeX(hObj); WM_GetInsideRectExScrollbar(hObj, &Rect); xSize = Rect.x1 - Rect.x0 + 1; IsRequired = (xSizeContents > xSize); WM_SetScrollbarH(hObj, IsRequired); } if (pObj->ScrollbarWidth) { LISTBOX__SetScrollbarWidth(hObj, pObj); } }
/********************************************************************* * * LISTBOX_GetItemDisabled */ int LISTBOX_GetItemDisabled(LISTBOX_Handle hObj, unsigned Index) { int Ret = 0; if (hObj) { unsigned NumItems; LISTBOX_Obj* pObj; WM_LOCK(); pObj = LISTBOX_H2P(hObj); NumItems = LISTBOX__GetNumItems(pObj); if (Index < NumItems) { WM_HMEM hItem = GUI_ARRAY_GethItem(&pObj->ItemArray, Index); if (hItem) { LISTBOX_ITEM * pItem = (LISTBOX_ITEM *)GUI_ALLOC_h2p(hItem); if (pItem->Status & LISTBOX_ITEM_DISABLED) { Ret = 1; } } } WM_UNLOCK(); } return Ret; }
/********************************************************************* * * LISTBOX_GetItemSel */ int LISTBOX_GetItemSel(LISTBOX_Handle hObj, unsigned Index) { int Ret = 0; if (hObj) { unsigned NumItems; LISTBOX_Obj* pObj; WM_LOCK(); pObj = LISTBOX_H2P(hObj); NumItems = LISTBOX__GetNumItems(pObj); if ((Index < NumItems) && (pObj->Flags & LISTBOX_SF_MULTISEL)) { WM_HMEM hItem = GUI_ARRAY_GethItem(&pObj->ItemArray, Index); if (hItem) { LISTBOX_ITEM * pItem = (LISTBOX_ITEM *)GUI_ALLOC_h2p(hItem); if (pItem->Status & LISTBOX_ITEM_SELECTED) { Ret = 1; } } } WM_UNLOCK(); } return Ret; }
/********************************************************************* * * LISTBOX_InsertString */ void LISTBOX_InsertString(LISTBOX_Handle hObj, const char* s, unsigned int Index) { if (hObj && s) { LISTBOX_Obj* pObj; unsigned int NumItems; WM_LOCK(); pObj = LISTBOX_H2P(hObj); NumItems = LISTBOX__GetNumItems(pObj); if (Index < NumItems) { WM_HMEM hItem; hItem = GUI_ARRAY_InsertItem(&pObj->ItemArray, Index, sizeof(LISTBOX_ITEM) + strlen(s)); if (hItem) { LISTBOX_ITEM* pItem = (LISTBOX_ITEM*)GUI_ALLOC_h2p(hItem); pItem->Status = 0; strcpy(pItem->acText, s); LISTBOX_InvalidateItem(hObj, Index); } } else { LISTBOX_AddString(hObj, s); } 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(); } }
/********************************************************************* * * _MoveSel * * Moves the selection/focus to the next valid item */ static void _MoveSel(LISTBOX_Handle hObj, int Dir) { int Index, NewSel = -1, NumItems; LISTBOX_Obj * pObj; pObj = LISTBOX_H2P(hObj); Index = LISTBOX_GetSel(hObj); NumItems = LISTBOX__GetNumItems(pObj); do { WM_HMEM hItem; Index += Dir; if ((Index < 0) || (Index >= NumItems)) { break; } hItem = GUI_ARRAY_GethItem(&pObj->ItemArray, Index); if (hItem) { LISTBOX_ITEM * pItem = (LISTBOX_ITEM *)GUI_ALLOC_h2p(hItem); if (!(pItem->Status & LISTBOX_ITEM_DISABLED)) { NewSel = Index; } } } while(NewSel < 0); if (NewSel >= 0) { LISTBOX_SetSel(hObj, NewSel); } }
/********************************************************************* * * 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(); } }