📄 listview.c
字号:
} else {
LCD_SetColor(pObj->Props.aTextColor[ColorIndex]);
}
/* Clear background */
GUI_ClearRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1);
/* Draw text */
Rect.x0 += LBorder;
Rect.x1 -= RBorder;
pColumn = (LISTVIEW_COLUMN*) GUI_ARRAY_GetpItem(&pObj->ColumnArray, j);
Align = pColumn->Align;
GUI_DispStringInRect(pCell->acText, &Rect, Align);
if (pCell->hCellInfo) {
LCD_SetBkColor(pObj->Props.aBkColor[ColorIndex]);
}
}
}
xPos += Width;
}
/* Clear unused area to the right of items */
if (xPos <= ClipRect.x1) {
GUI_ClearRect(xPos, Rect.y0, ClipRect.x1, Rect.y1);
}
}
yPos += RowDistY;
}
}
/* Clear unused area below items */
if (yPos <= ClipRect.y1) {
LCD_SetBkColor(pObj->Props.aBkColor[0]);
GUI_ClearRect(ClipRect.x0, yPos, ClipRect.x1, ClipRect.y1);
}
/* Draw grid */
if (pObj->ShowGrid) {
LCD_SetColor(pObj->Props.GridColor);
yPos = HEADER_GetHeight(pObj->hHeader) + EffectSize - 1;
for (i = 0; i < NumVisRows; i++) {
yPos += RowDistY;
/* Break when all other rows are outside the drawing area */
if (yPos > ClipRect.y1) {
break;
}
/* Make sure that we draw only when row is in drawing area */
if (yPos >= ClipRect.y0) {
GUI_DrawHLine(yPos, ClipRect.x0, ClipRect.x1);
}
}
xPos = EffectSize - pObj->ScrollStateH.v;
for (i = 0; i < NumColumns; i++) {
xPos += HEADER_GetItemWidth(pObj->hHeader, i);
/* Break when all other columns are outside the drawing area */
if (xPos > ClipRect.x1) {
break;
}
/* Make sure that we draw only when column is in drawing area */
if (xPos >= ClipRect.x0) {
GUI_DrawVLine(xPos, ClipRect.y0, ClipRect.y1);
}
}
}
/* Draw the effect */
WIDGET__EFFECT_DrawDown(&pObj->Widget);
}
/*********************************************************************
*
* LISTVIEW__InvalidateInsideArea
*/
void LISTVIEW__InvalidateInsideArea(LISTVIEW_Handle hObj, LISTVIEW_Obj* pObj) {
GUI_RECT Rect;
int HeaderHeight;
HeaderHeight = HEADER_GetHeight(pObj->hHeader);
WM_GetInsideRectExScrollbar(hObj, &Rect);
Rect.y0 += HeaderHeight;
WM_InvalidateRect(hObj, &Rect);
}
/*********************************************************************
*
* LISTVIEW__InvalidateRow
*/
void LISTVIEW__InvalidateRow(LISTVIEW_Handle hObj, LISTVIEW_Obj* pObj, int Sel) {
if (Sel >= 0) {
GUI_RECT Rect;
int HeaderHeight, RowDistY;
HeaderHeight = HEADER_GetHeight(pObj->hHeader);
RowDistY = LISTVIEW__GetRowDistY(pObj);
WM_GetInsideRectExScrollbar(hObj, &Rect);
Rect.y0 += HeaderHeight + (Sel - pObj->ScrollStateV.v) * RowDistY;
Rect.y1 = Rect.y0 + RowDistY - 1;
WM_InvalidateRect(hObj, &Rect);
}
}
/*********************************************************************
*
* _SetSelFromPos
*/
static void _SetSelFromPos(LISTVIEW_Handle hObj, LISTVIEW_Obj* pObj, const GUI_PID_STATE* pState) {
GUI_RECT Rect;
int x, y, HeaderHeight;
HeaderHeight = HEADER_GetHeight(pObj->hHeader);
WM_GetInsideRectExScrollbar(hObj, &Rect);
x = pState->x - Rect.x0;
y = pState->y - Rect.y0 - HeaderHeight;
Rect.x1 -= Rect.x0;
Rect.y1 -= Rect.y0;
if ((x >= 0) && (x <= Rect.x1) && (y >= 0) && (y <= (Rect.y1 - HeaderHeight))) {
unsigned Sel;
Sel = (y / LISTVIEW__GetRowDistY(pObj)) + pObj->ScrollStateV.v;
if (Sel < LISTVIEW__GetNumRows(pObj)) {
LISTVIEW__SetSel(hObj, pObj, Sel);
}
}
}
/*********************************************************************
*
* _NotifyOwner
*
* Purpose:
* Notify owner of the window.
* If no owner is registered, the parent is considered owner.
*/
static void _NotifyOwner(WM_HWIN hObj, int Notification) {
WM_MESSAGE Msg = {0};
WM_HWIN hOwner;
LISTVIEW_Obj* pObj = LISTVIEW_H2P(hObj);
hOwner = pObj->hOwner ? pObj->hOwner : WM_GetParent(hObj);
Msg.MsgId = WM_NOTIFY_PARENT;
Msg.Data.v = Notification;
Msg.hWinSrc = hObj;
WM__SendMessage(hOwner, &Msg);
}
/*********************************************************************
*
* _OnTouch
*/
static void _OnTouch(LISTVIEW_Handle hObj, LISTVIEW_Obj* pObj, WM_MESSAGE*pMsg) {
int Notification;
const GUI_PID_STATE* pState = (const GUI_PID_STATE*)pMsg->Data.p;
GUI_USE_PARA(pObj);
if (pMsg->Data.p) { /* Something happened in our area (pressed or released) */
if (pState->Pressed) {
_SetSelFromPos(hObj, pObj, pState);
Notification = WM_NOTIFICATION_CLICKED;
WM_SetFocus(hObj);
} else {
Notification = WM_NOTIFICATION_RELEASED;
}
} else {
Notification = WM_NOTIFICATION_MOVED_OUT;
}
_NotifyOwner(hObj, Notification);
}
/*********************************************************************
*
* _GetXSize
*
* Purpose:
* Returns the width of the inside listview area.
*/
static int _GetXSize(LISTVIEW_Handle hObj) {
GUI_RECT Rect;
WM_GetInsideRectExScrollbar(hObj, &Rect);
return Rect.x1 - Rect.x0 + 1;
}
/*********************************************************************
*
* _GetHeaderWidth
*
* Purpose:
* Returns the width of all items in header.
*
* Return value:
* NumItems > 0: width of all items.
* NumItems = 0: 1 (to avoid problem with horizontal scrollbar)
*/
static int _GetHeaderWidth(LISTVIEW_Obj * pObj) {
int NumItems, i, r = 1;
NumItems = HEADER_GetNumItems(pObj->hHeader);
if (NumItems) {
for (i = 0, r = 0; i < NumItems; i++) {
r += HEADER_GetItemWidth(pObj->hHeader, i);
}
}
return r;
}
/*********************************************************************
*
* LISTVIEW__UpdateScrollPos
*
* Purpose:
* Checks whether if we must scroll up or scroll down to ensure
* that selection is in the visible area. This function also
* makes sure that scroll positions are in valid ranges.
*
* Return value:
* Difference between old and new vertical scroll pos.
*/
int LISTVIEW__UpdateScrollPos(LISTVIEW_Handle hObj, LISTVIEW_Obj* pObj) {
int PrevScrollStateV;
PrevScrollStateV = pObj->ScrollStateV.v;
if (pObj->Sel >= 0) {
WM_CheckScrollPos(&pObj->ScrollStateV, pObj->Sel, 0, 0);
} else {
WM_CheckScrollBounds(&pObj->ScrollStateV);
}
WM_CheckScrollBounds(&pObj->ScrollStateH);
WIDGET__SetScrollState(hObj, &pObj->ScrollStateV, &pObj->ScrollStateH);
return pObj->ScrollStateV.v - PrevScrollStateV;
}
/*********************************************************************
*
* LISTVIEW__UpdateScrollParas
*
* Purpose:
* Calculates number of items and page size of both vertical
* and horizontal scrollbar. After this LISTVIEW__UpdateScrollPos will
* be called to ensure scroll positions are in valid ranges.
*/
int LISTVIEW__UpdateScrollParas(LISTVIEW_Handle hObj, LISTVIEW_Obj* pObj) {
int NumRows, IsRequired;
int xSize, xSizeHeader;
unsigned NumVisibleRows;
NumVisibleRows = _GetNumVisibleRows(hObj, pObj);
xSize = _GetXSize(hObj);
xSizeHeader = _GetHeaderWidth(pObj);
if (pObj->Flags & LISTVIEW_SF_AUTOSCROLLBAR_V) {
IsRequired = (NumVisibleRows < GUI_ARRAY_GetNumItems(&pObj->RowArray));
WM_SetScrollbarV(hObj, IsRequired);
}
if (pObj->Flags & LISTVIEW_SF_AUTOSCROLLBAR_H) {
IsRequired = (xSizeHeader > xSize);
WM_SetScrollbarH(hObj, IsRequired);
NumVisibleRows = _GetNumVisibleRows(hObj, pObj);
}
NumRows = LISTVIEW__GetNumRows(pObj);
/* update vertical scrollbar */
pObj->ScrollStateV.PageSize = NumVisibleRows;
pObj->ScrollStateV.NumItems = (NumRows) ? NumRows : 1;
/* update horizontal scrollbar */
pObj->ScrollStateH.PageSize = xSize;
pObj->ScrollStateH.NumItems = xSizeHeader;
return LISTVIEW__UpdateScrollPos(hObj, pObj);
}
/*********************************************************************
*
* _FreeAttached
*
* Purpose:
* Delete attached objects (if any).
*/
static void _FreeAttached(LISTVIEW_Obj * pObj) {
int i, j, NumRows, NumColumns;
NumRows = LISTVIEW__GetNumRows(pObj);
NumColumns = LISTVIEW__GetNumColumns(pObj);
for (i = 0; i < NumRows; i++) {
LISTVIEW_ROW* pRow;
pRow = (LISTVIEW_ROW*) GUI_ARRAY_GetpItem(&pObj->RowArray, i);
/* Delete attached info items */
for (j = 0; j < NumColumns; j++) {
LISTVIEW_CELL* pCell;
pCell = (LISTVIEW_CELL*) GUI_ARRAY_GetpItem(&pRow->CellArray, j);
if (pCell) {
if (pCell->hCellInfo) {
GUI_ALLOC_Free(pCell->hCellInfo);
}
}
}
/* Delete row */
GUI_ARRAY_Delete(&pRow->CellArray);
}
/* Delete sort object */
if (pObj->hSort) {
((LISTVIEW_SORT *)GUI_ALLOC_h2p(pObj->hSort))->fpFree(pObj->hSort);
}
GUI_ARRAY_Delete(&pObj->ColumnArray);
GUI_ARRAY_Delete(&pObj->RowArray);
}
/*********************************************************************
*
* _OnPage
*
* Purpose:
* Handles pressing of GUI_KEY_PGUP and GUI_KEY_PGDOWN
*
* Parameters:
* Dir > 0: If the current selection is not on the bottom row, the selection
* will be moved to the bottom row.
* If the current selection is on the bottom row, the selection will
* be moved one page down. If not possible, the bottom row will be selected.
* Dir < 0: If the current selection is not on the top row, the selection
* will be moved to the top row.
* If the current selection is on the top row, the selection will
* be moved one page up. If not possible, the top row will be selected.
*/
static void _OnPage(LISTVIEW_Handle hObj, LISTVIEW_Obj * pObj, int Dir) {
if (Dir < 0) {
/* Check if cursor is already on top row of the page */
if (pObj->Sel != pObj->ScrollStateV.v) {
/* If not, set cursor on top row */
LISTVIEW__SetSel(hObj, pObj, pObj->ScrollStateV.v);
} else {
/* Check if current selection is >= one page size */
if (pObj->Sel >= pObj->ScrollStateV.PageSize) {
/* Move selection one page up */
LISTVIEW__MoveSel(hObj, pObj, -pObj->ScrollStateV.PageSize);
} else {
/* Set selection on top row */
LISTVIEW__SetSel(hObj, pObj, 0);
}
}
} else {
int Pos;
/* Check if cursor is already on bottom row of the page */
Pos = pObj->ScrollStateV.v + pObj->ScrollStateV.PageSize - 1;
if (pObj->Sel != Pos) {
/* If not, set cursor on bottom row */
LISTVIEW__SetSel(hObj, pObj, Pos);
} else {
int NumItems;
/* Check if current selection is <= (NumItems - PageSize - 1) */
NumItems = LISTVIEW__GetNumRows(pObj);
if (pObj->Sel < (NumItems - pObj->ScrollStateV.PageSize - 1)) {
/* Move selection one page down */
LISTVIEW__MoveSel(hObj, pObj, pObj->ScrollStateV.PageSize);
} else {
/* Set selection on bottom row */
LISTVIEW__SetSel(hObj, pObj, NumItems - 1);
}
}
}
}
/*********************************************************************
*
* _AddKey
*
* Returns: 1 if Key has been consumed
* 0 else
*/
static int _AddKey(LISTVIEW_Handle hObj, LISTVIEW_Obj* pObj, int Key) {
switch (Key) {
case GUI_KEY_DOWN:
LISTVIEW__MoveSel(hObj, pObj, 1);
return 1; /* Key has been consumed */
case GUI_KEY_PGDOWN:
_OnPage(hObj, pObj, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -