/********************************************************************* * * _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); }
/********************************************************************* * * 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); } } }
/********************************************************************* * * _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; }
/********************************************************************* * * _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; }
/********************************************************************* * * _OwnerDraw * * Purpose: * This is the owner draw function. * It allows complete customization of how the items in the listbox are * drawn. A command specifies what the function should do; * The minimum is to react to the draw command (WIDGET_ITEM_DRAW); * If the item x-size differs from the default, then this information * needs to be returned in reaction to WIDGET_ITEM_GET_XSIZE. * To insure compatibility with future version, all unhandled commands * must call the default routine LISTBOX_OwnerDraw. */ static int _OwnerDraw(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo) { WM_HWIN hWin; int Index; hWin = pDrawItemInfo->hWin; Index = pDrawItemInfo->ItemIndex; switch (pDrawItemInfo->Cmd) { case WIDGET_ITEM_GET_XSIZE: return _GetItemSizeX(hWin, Index); case WIDGET_ITEM_GET_YSIZE: return _GetItemSizeY(hWin, Index); case WIDGET_ITEM_DRAW: { int MultiSel, Sel, YSize, FontDistY; int IsDisabled, IsSelected; int ColorIndex = 0; char acBuffer[100]; const GUI_BITMAP * pBm; const GUI_FONT* pOldFont = 0; GUI_COLOR aColor[4] = {GUI_BLACK, GUI_WHITE, GUI_WHITE, GUI_GRAY}; GUI_COLOR aBkColor[4] = {GUI_WHITE, GUI_GRAY, GUI_BLUE, 0xC0C0C0}; IsDisabled = LISTBOX_GetItemDisabled(pDrawItemInfo->hWin, pDrawItemInfo->ItemIndex); IsSelected = LISTBOX_GetItemSel(hWin, Index); MultiSel = LISTBOX_GetMulti(hWin); Sel = LISTBOX_GetSel(hWin); YSize = _GetItemSizeY(hWin, Index); /* Calculate color index */ if (MultiSel) { if (IsDisabled) { ColorIndex = 3; } else { ColorIndex = (IsSelected) ? 2 : 0; } } else { if (IsDisabled) { ColorIndex = 3; } else { if (pDrawItemInfo->ItemIndex == Sel) { ColorIndex = WM_HasFocus(pDrawItemInfo->hWin) ? 2 : 1; } else { ColorIndex = 0; } } } /* Draw item */ GUI_SetBkColor(aBkColor[ColorIndex]); GUI_SetColor (aColor[ColorIndex]); LISTBOX_GetItemText(pDrawItemInfo->hWin, pDrawItemInfo->ItemIndex, acBuffer, sizeof(acBuffer)); GUI_Clear(); if ((ColorIndex == 1) || (ColorIndex == 2)) { pOldFont = GUI_SetFont(&GUI_Font13B_1); } FontDistY = GUI_GetFontDistY(); GUI_DispStringAt(acBuffer, pDrawItemInfo->x0 + bmSmilie0.XSize + 16, pDrawItemInfo->y0 + (YSize - FontDistY) / 2); if (pOldFont) { GUI_SetFont(pOldFont); } GUI_DispCEOL(); /* Draw bitmap */ pBm = MultiSel ? IsSelected ? &bmSmilie1 : &bmSmilie0 : (pDrawItemInfo->ItemIndex == Sel) ? &bmSmilie1 : &bmSmilie0; GUI_DrawBitmap(pBm, pDrawItemInfo->x0 + 7, pDrawItemInfo->y0 + (YSize - pBm->YSize) / 2); /* Draw focus rectangle */ if (MultiSel && (pDrawItemInfo->ItemIndex == Sel)) { GUI_RECT rFocus; GUI_RECT rInside; WM_GetInsideRectEx(pDrawItemInfo->hWin, &rInside); rFocus.x0 = pDrawItemInfo->x0; rFocus.y0 = pDrawItemInfo->y0; rFocus.x1 = rInside.x1; rFocus.y1 = pDrawItemInfo->y0 + YSize - 1; GUI_SetColor(GUI_WHITE - aBkColor[ColorIndex]); GUI_DrawFocusRect(&rFocus, 0); } } break; default: return LISTBOX_OwnerDraw(pDrawItemInfo); } return 0; }