mirror of
https://gitee.com/Polarix/simplegui.git
synced 2025-06-18 05:57:53 +00:00
244 lines
11 KiB
C
244 lines
11 KiB
C
/*************************************************************************/
|
|
/** Copyright. **/
|
|
/** FileName: SGUI_ItemsBase.c **/
|
|
/** Author: XuYulin **/
|
|
/** Description: Simple GUI items base interface, used to extend list **/
|
|
/** components . **/
|
|
/*************************************************************************/
|
|
|
|
//=======================================================================//
|
|
//= Include files. =//
|
|
//=======================================================================//
|
|
#include "SGUI_ItemsBase.h"
|
|
|
|
//=======================================================================//
|
|
//= Static function declaration. =//
|
|
//=======================================================================//
|
|
|
|
//=======================================================================//
|
|
//= Function define. =//
|
|
//=======================================================================//
|
|
/*************************************************************************/
|
|
/** Function Name: SGUI_ItemsBase_Initialize **/
|
|
/** Purpose: Initialize a items-base object data. **/
|
|
/** Params: **/
|
|
/** @ pstObj[in]: Pointer of items-base object will be initialized. **/
|
|
/** @ pstFontRes[in]: Font resource object pointer. **/
|
|
/** @ pstItemsData[in]: Items data array. **/
|
|
/** @ iItemsCount[in]: Number of list item data. **/
|
|
/** Return: None. **/
|
|
/*************************************************************************/
|
|
void SGUI_ItemsBase_Initialize(SGUI_ITEMS_BASE* pstObj, const SGUI_FONT_RES* pstFontRes, SGUI_ITEMS_ITEM* pstItemsData, SGUI_INT iItemsCount)
|
|
{
|
|
/*----------------------------------*/
|
|
/* Process */
|
|
/*----------------------------------*/
|
|
if((NULL != pstObj) && (NULL != pstFontRes))
|
|
{
|
|
pstObj->pstItems = pstItemsData;
|
|
pstObj->iCount = iItemsCount;
|
|
pstObj->pstFontRes = pstFontRes;
|
|
pstObj->iSelection = 0;
|
|
pstObj->iVisibleItems = (pstObj->stLayout.iHeight-1)/ITEM_HEIGHT(pstObj->pstFontRes)+1;
|
|
pstObj->iPageStartIndex = 0;
|
|
pstObj->iPageEndIndex = pstObj->iVisibleItems - 1;
|
|
pstObj->iItemPaintOffset = 0;
|
|
}
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/** Function Name: SGUI_ItemsBase_Repaint **/
|
|
/** Purpose: Update list display on screen. **/
|
|
/** Params: **/
|
|
/** @ pstDeviceIF[in]: Device driver object pointer. **/
|
|
/** @ pstObj[in]: Pointer of items-base object will be paint. **/
|
|
/** Return: None. **/
|
|
/*************************************************************************/
|
|
void SGUI_ItemsBase_Repaint(SGUI_SCR_DEV* pstDeviceIF, SGUI_ITEMS_BASE* pstObj)
|
|
{
|
|
/*----------------------------------*/
|
|
/* Variable Declaration */
|
|
/*----------------------------------*/
|
|
SGUI_RECT stItemPaintArea;
|
|
SGUI_POINT stItemTextPos;
|
|
SGUI_INT iItemIndex;
|
|
SGUI_CSZSTR cszItemText;
|
|
|
|
/*----------------------------------*/
|
|
/* Initialize */
|
|
/*----------------------------------*/
|
|
stItemTextPos.iX = 1;
|
|
|
|
/*----------------------------------*/
|
|
/* Process */
|
|
/*----------------------------------*/
|
|
if((NULL != pstDeviceIF) && (NULL != pstObj))
|
|
{
|
|
// Clear background
|
|
SGUI_Basic_DrawRectangle(pstDeviceIF, pstObj->stLayout.iX, pstObj->stLayout.iY, pstObj->stLayout.iWidth, pstObj->stLayout.iHeight, SGUI_COLOR_BKGCLR, SGUI_COLOR_BKGCLR);
|
|
if((pstObj->iSelection > SGUI_INVALID_INDEX) && (pstObj->iSelection < pstObj->iCount))
|
|
{
|
|
stItemPaintArea.iX = pstObj->stLayout.iX;
|
|
stItemPaintArea.iY = pstObj->stLayout.iY;
|
|
stItemPaintArea.iWidth = pstObj->stLayout.iWidth;
|
|
/* Judge selected item is in visible area. */
|
|
if(pstObj->iSelection < pstObj->iPageStartIndex)
|
|
{
|
|
pstObj->iPageStartIndex = pstObj->iSelection;
|
|
pstObj->iPageEndIndex = pstObj->iPageStartIndex + pstObj->iVisibleItems - 1;
|
|
}
|
|
else if(pstObj->iSelection > pstObj->iPageEndIndex)
|
|
{
|
|
pstObj->iPageEndIndex = pstObj->iSelection;
|
|
pstObj->iPageStartIndex = pstObj->iPageEndIndex - pstObj->iVisibleItems + 1;
|
|
}
|
|
/* Judge selected item is beginning or ending. */
|
|
if(pstObj->iSelection == pstObj->iPageStartIndex)
|
|
{
|
|
pstObj->iItemPaintOffset = 0;
|
|
stItemPaintArea.iHeight = (pstObj->iVisibleItems>1)?(ITEM_HEIGHT(pstObj->pstFontRes)):(pstObj->stLayout.iHeight);
|
|
}
|
|
else if(pstObj->iSelection == pstObj->iPageEndIndex)
|
|
{
|
|
pstObj->iItemPaintOffset = (((pstObj->stLayout.iHeight)%ITEM_HEIGHT(pstObj->pstFontRes))-ITEM_HEIGHT(pstObj->pstFontRes))%ITEM_HEIGHT(pstObj->pstFontRes);
|
|
stItemPaintArea.iHeight = ITEM_HEIGHT(pstObj->pstFontRes)+pstObj->iItemPaintOffset;
|
|
}
|
|
else
|
|
{
|
|
stItemPaintArea.iHeight = ITEM_HEIGHT(pstObj->pstFontRes);
|
|
}
|
|
|
|
/* Paint first visible item. */
|
|
iItemIndex=pstObj->iPageStartIndex;
|
|
stItemTextPos.iY = pstObj->iItemPaintOffset+1;
|
|
cszItemText = (NULL==pstObj->pstItems[iItemIndex].szVariableText)?pstObj->pstItems[iItemIndex].cszLabelText:pstObj->pstItems[iItemIndex].szVariableText;
|
|
SGUI_Text_DrawText(pstDeviceIF, cszItemText, pstObj->pstFontRes, &stItemPaintArea, &stItemTextPos, iItemIndex==pstObj->iSelection?SGUI_DRAW_REVERSE:SGUI_DRAW_NORMAL);
|
|
iItemIndex++;
|
|
stItemPaintArea.iHeight = ITEM_HEIGHT(pstObj->pstFontRes);
|
|
if(pstObj->iVisibleItems > 1)
|
|
{
|
|
stItemPaintArea.iY += ITEM_HEIGHT(pstObj->pstFontRes)+(pstObj->iItemPaintOffset);
|
|
stItemTextPos.iY = 1;
|
|
while((iItemIndex != pstObj->iPageEndIndex) && (iItemIndex < pstObj->iCount))
|
|
{
|
|
cszItemText = (NULL==pstObj->pstItems[iItemIndex].szVariableText)?pstObj->pstItems[iItemIndex].cszLabelText:pstObj->pstItems[iItemIndex].szVariableText;
|
|
SGUI_Text_DrawText(pstDeviceIF, cszItemText, pstObj->pstFontRes, &stItemPaintArea, &stItemTextPos, iItemIndex==pstObj->iSelection?SGUI_DRAW_REVERSE:SGUI_DRAW_NORMAL);
|
|
stItemPaintArea.iY += ITEM_HEIGHT(pstObj->pstFontRes);
|
|
iItemIndex++;
|
|
}
|
|
if(iItemIndex < pstObj->iCount)
|
|
{
|
|
/* Paint last visible item. */
|
|
stItemPaintArea.iHeight = (0==pstObj->iItemPaintOffset)?(pstObj->stLayout.iHeight%ITEM_HEIGHT(pstObj->pstFontRes)):(ITEM_HEIGHT(pstObj->pstFontRes));
|
|
/* Correct last visible item height when items area height is an integer multiple of item height. */
|
|
stItemPaintArea.iHeight = (0==stItemPaintArea.iHeight)?ITEM_HEIGHT(pstObj->pstFontRes):stItemPaintArea.iHeight;
|
|
cszItemText = (NULL==pstObj->pstItems[iItemIndex].szVariableText)?pstObj->pstItems[iItemIndex].cszLabelText:pstObj->pstItems[iItemIndex].szVariableText;
|
|
SGUI_Text_DrawText(pstDeviceIF, cszItemText, pstObj->pstFontRes, &stItemPaintArea, &stItemTextPos, iItemIndex==pstObj->iSelection?SGUI_DRAW_REVERSE:SGUI_DRAW_NORMAL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/** Function Name: SGUI_ItemsBase_GetItem **/
|
|
/** Purpose: Get item object pointer by index. **/
|
|
/** Params: **/
|
|
/** @ pstObj[in]: Pointer of items-base object will be paint. **/
|
|
/** @ iIndex[in]: Index of wanted item. **/
|
|
/** Return: Item object pointer. **/
|
|
/*************************************************************************/
|
|
SGUI_ITEMS_ITEM* SGUI_ItemsBase_GetItem(SGUI_ITEMS_BASE* pstObj, SGUI_INT iIndex)
|
|
{
|
|
/*----------------------------------*/
|
|
/* Variable Declaration */
|
|
/*----------------------------------*/
|
|
SGUI_ITEMS_ITEM* pstSelectedItem;
|
|
|
|
/*----------------------------------*/
|
|
/* Initialize */
|
|
/*----------------------------------*/
|
|
pstSelectedItem = NULL;
|
|
|
|
/*----------------------------------*/
|
|
/* Process */
|
|
/*----------------------------------*/
|
|
if((NULL != pstObj) && (iIndex > SGUI_INVALID_INDEX) && (iIndex < pstObj->iCount))
|
|
{
|
|
pstSelectedItem = pstObj->pstItems+iIndex;
|
|
}
|
|
|
|
return pstSelectedItem;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/** Function Name: SGUI_ItemsBase_GetItemExtent **/
|
|
/** Purpose: Get item object display area position and size. **/
|
|
/** Params: **/
|
|
/** @ pstObj[in]: Pointer of items-base object will be paint. **/
|
|
/** @ iSelection[in]: Selected item index. **/
|
|
/** @ pstItemExtent[out]: Item position and display area size. **/
|
|
/** Return: None. **/
|
|
/** Notice: This function only used for the visible item, if **/
|
|
/** selection is invisible, output size will be (0, 0). **/
|
|
/*************************************************************************/
|
|
void SGUI_ItemsBase_GetItemExtent(SGUI_ITEMS_BASE* pstObj, SGUI_INT iSelection, SGUI_RECT* pstItemExtent)
|
|
{
|
|
/*----------------------------------*/
|
|
/* Process */
|
|
/*----------------------------------*/
|
|
if((NULL != pstObj) && (iSelection > SGUI_INVALID_INDEX) && (iSelection < pstObj->iCount) && (NULL != pstItemExtent))
|
|
{
|
|
pstItemExtent->iX = pstObj->stLayout.iX;
|
|
pstItemExtent->iWidth = pstObj->stLayout.iWidth;
|
|
/* Item is not visible. */
|
|
if((iSelection < pstObj->iPageStartIndex) || (iSelection > pstObj->iPageEndIndex))
|
|
{
|
|
pstItemExtent->iY = 0;
|
|
pstItemExtent->iHeight = 0;
|
|
}
|
|
else
|
|
{
|
|
if((0 == pstObj->iItemPaintOffset) && (iSelection == pstObj->iPageEndIndex))
|
|
{
|
|
pstItemExtent->iY = pstObj->stLayout.iY+(ITEM_HEIGHT(pstObj->pstFontRes)*(pstObj->iVisibleItems-1));
|
|
pstItemExtent->iHeight = (0==pstObj->iItemPaintOffset)?(pstObj->stLayout.iHeight%ITEM_HEIGHT(pstObj->pstFontRes)):(ITEM_HEIGHT(pstObj->pstFontRes));
|
|
/* Correct last visible item height when items area height is an integer multiple of item height. */
|
|
pstItemExtent->iHeight = (0==pstItemExtent->iHeight)?ITEM_HEIGHT(pstObj->pstFontRes):pstItemExtent->iHeight;
|
|
}
|
|
else if((0 != pstObj->iItemPaintOffset) && (iSelection == pstObj->iPageStartIndex))
|
|
{
|
|
pstItemExtent->iY = pstObj->stLayout.iY;
|
|
pstItemExtent->iHeight = ITEM_HEIGHT(pstObj->pstFontRes)+pstObj->iItemPaintOffset;
|
|
}
|
|
else
|
|
{
|
|
pstItemExtent->iY = pstObj->stLayout.iY+((iSelection - pstObj->iPageStartIndex)*ITEM_HEIGHT(pstObj->pstFontRes))+pstObj->iItemPaintOffset;
|
|
pstItemExtent->iHeight = ITEM_HEIGHT(pstObj->pstFontRes);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/** Function Name: SGUI_ItemsBase_FitLayout **/
|
|
/** Purpose: Recalculate layout data when display area size is **/
|
|
/** changed. **/
|
|
/** Params: **/
|
|
/** @ pstObj[in]: Pointer of items-base object will be paint. **/
|
|
/** Return: None. **/
|
|
/** Notice: This function only used for the visible item, if **/
|
|
/** selection is invisible, output size will be (0, 0). **/
|
|
/*************************************************************************/
|
|
void SGUI_ItemsBase_FitLayout(SGUI_ITEMS_BASE* pstObj)
|
|
{
|
|
/*----------------------------------*/
|
|
/* Process */
|
|
/*----------------------------------*/
|
|
if(NULL != pstObj)
|
|
{
|
|
pstObj->iVisibleItems = (pstObj->stLayout.iHeight-1)/ITEM_HEIGHT(pstObj->pstFontRes)+1;
|
|
pstObj->iPageEndIndex = pstObj->iPageStartIndex + pstObj->iVisibleItems - 1;
|
|
}
|
|
}
|