📄 listview.c
字号:
/*
*********************************************************************************************************
* uC/GUI V3.98
* Universal graphic software for embedded applications
*
* (c) Copyright 2002, Micrium Inc., Weston, FL
* (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
*
* 礐/GUI is protected by international copyright laws. Knowledge of the
* source code may not be used to write a similar product. This file may
* only be used in accordance with a license and should not be redistributed
* in any way. We appreciate your understanding and fairness.
*
----------------------------------------------------------------------
File : LISTVIEW.c
Purpose : Implementation of listview widget
---------------------------END-OF-HEADER------------------------------
*/
#include "GUI_ARRAY.h"
#include <stdlib.h>
#include <string.h>
#include "LISTVIEW_Private.h"
#include "HEADER.h"
#include "WIDGET.h"
#include "SCROLLBAR.h"
#include "GUIDebug.h"
#include "GUI_Protected.h"
#include "WM_Intern.h"
#if GUI_WINSUPPORT
/*********************************************************************
*
* Private config defaults
*
**********************************************************************
*/
/* Define default fonts */
#ifndef LISTVIEW_FONT_DEFAULT
#if WIDGET_USE_SCHEME_SMALL
#define LISTVIEW_FONT_DEFAULT &GUI_Font13_1
#elif WIDGET_USE_SCHEME_MEDIUM
#define LISTVIEW_FONT_DEFAULT &GUI_Font16_1
#elif WIDGET_USE_SCHEME_LARGE
#define LISTVIEW_FONT_DEFAULT &GUI_Font24_1
#endif
#endif
/* Define colors */
#ifndef LISTVIEW_BKCOLOR0_DEFAULT
#define LISTVIEW_BKCOLOR0_DEFAULT GUI_WHITE /* Not selected */
#endif
#ifndef LISTVIEW_BKCOLOR1_DEFAULT
#define LISTVIEW_BKCOLOR1_DEFAULT GUI_GRAY /* Selected, no focus */
#endif
#ifndef LISTVIEW_BKCOLOR2_DEFAULT
#define LISTVIEW_BKCOLOR2_DEFAULT GUI_BLUE /* Selected, focus */
#endif
#ifndef LISTVIEW_BKCOLOR3_DEFAULT
#define LISTVIEW_BKCOLOR3_DEFAULT GUI_LIGHTGRAY /* Disabled */
#endif
#ifndef LISTVIEW_TEXTCOLOR0_DEFAULT
#define LISTVIEW_TEXTCOLOR0_DEFAULT GUI_BLACK /* Not selected */
#endif
#ifndef LISTVIEW_TEXTCOLOR1_DEFAULT
#define LISTVIEW_TEXTCOLOR1_DEFAULT GUI_WHITE /* Selected, no focus */
#endif
#ifndef LISTVIEW_TEXTCOLOR2_DEFAULT
#define LISTVIEW_TEXTCOLOR2_DEFAULT GUI_WHITE /* Selected, focus */
#endif
#ifndef LISTVIEW_TEXTCOLOR3_DEFAULT
#define LISTVIEW_TEXTCOLOR3_DEFAULT GUI_GRAY /* Disabled */
#endif
#ifndef LISTVIEW_GRIDCOLOR_DEFAULT
#define LISTVIEW_GRIDCOLOR_DEFAULT GUI_LIGHTGRAY
#endif
/* Define default alignment */
#ifndef LISTVIEW_ALIGN_DEFAULT
#define LISTVIEW_ALIGN_DEFAULT (GUI_TA_VCENTER | GUI_TA_HCENTER)
#endif
#ifndef LISTVIEW_SCROLLSTEP_H_DEFAULT
#define LISTVIEW_SCROLLSTEP_H_DEFAULT 10
#endif
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
LISTVIEW_PROPS LISTVIEW_DefaultProps = {
LISTVIEW_BKCOLOR0_DEFAULT,
LISTVIEW_BKCOLOR1_DEFAULT,
LISTVIEW_BKCOLOR2_DEFAULT,
LISTVIEW_BKCOLOR3_DEFAULT,
LISTVIEW_TEXTCOLOR0_DEFAULT,
LISTVIEW_TEXTCOLOR1_DEFAULT,
LISTVIEW_TEXTCOLOR2_DEFAULT,
LISTVIEW_TEXTCOLOR3_DEFAULT,
LISTVIEW_GRIDCOLOR_DEFAULT,
LISTVIEW_FONT_DEFAULT,
LISTVIEW_SCROLLSTEP_H_DEFAULT
};
/*********************************************************************
*
* Static routines
*
**********************************************************************
*/
/*********************************************************************
*
* LISTVIEW__GetNumRows
*/
unsigned LISTVIEW__GetNumRows(LISTVIEW_Obj* pObj) {
return GUI_ARRAY_GetNumItems(&pObj->RowArray);
}
/*********************************************************************
*
* LISTVIEW__GetNumColumns
*/
unsigned LISTVIEW__GetNumColumns(LISTVIEW_Obj* pObj) {
return GUI_ARRAY_GetNumItems(&pObj->ColumnArray);
}
/*********************************************************************
*
* LISTVIEW__GetSel
*/
int LISTVIEW__GetSel(LISTVIEW_Obj* pObj) {
return pObj->Sel;
}
/*********************************************************************
*
* LISTVIEW__SetSel
*/
void LISTVIEW__SetSel(LISTVIEW_Handle hObj, LISTVIEW_Obj* pObj, int NewSel) {
int NumRows;
NumRows = LISTVIEW__GetNumRows(pObj);
if (NewSel >= NumRows) {
NewSel = NumRows - 1;
}
if (NewSel < 0) {
NewSel = -1;
}
if (NewSel != pObj->Sel) {
char Disabled;
LISTVIEW_ROW * pRow;
pRow = (LISTVIEW_ROW *)GUI_ARRAY_GetpItem(&pObj->RowArray, NewSel);
if (pRow) {
Disabled = pRow->Disabled;
} else {
Disabled = 0;
}
if (Disabled == 0) {
int OldSel;
OldSel = pObj->Sel;
pObj->Sel = NewSel;
if (LISTVIEW__UpdateScrollPos(hObj, pObj)) {
LISTVIEW__InvalidateInsideArea(hObj, pObj);
} else {
LISTVIEW__InvalidateRow(hObj, pObj, OldSel);
LISTVIEW__InvalidateRow(hObj, pObj, NewSel);
}
WM_NotifyParent(hObj, WM_NOTIFICATION_SEL_CHANGED);
}
}
}
/*********************************************************************
*
* LISTVIEW__MoveSel
*
* Moves the selection to the next valid item.
*/
void LISTVIEW__MoveSel(LISTVIEW_Handle hObj, LISTVIEW_Obj* pObj, int Dir) {
int Index, NewSel = -1, NumRows;
Index = LISTVIEW__GetSel(pObj);
NumRows = LISTVIEW__GetNumRows(pObj);
do {
LISTVIEW_ROW* pRow;
Index += Dir;
if ((Index < 0) || (Index >= NumRows)) {
break;
}
pRow = (LISTVIEW_ROW*) GUI_ARRAY_GetpItem(&pObj->RowArray, Index);
if (pRow->Disabled == 0) {
NewSel = Index;
}
} while (NewSel < 0);
if (NewSel >= 0) {
LISTVIEW__SetSel(hObj, pObj, NewSel);
}
}
/*********************************************************************
*
* LISTVIEW__GetRowDistY
*/
unsigned LISTVIEW__GetRowDistY(const LISTVIEW_Obj* pObj) {
unsigned RowDistY;
if (pObj->RowDistY) {
RowDistY = pObj->RowDistY;
} else {
RowDistY = GUI_GetYDistOfFont(pObj->Props.pFont);
if (pObj->ShowGrid) {
RowDistY++;
}
}
return RowDistY;
}
/*********************************************************************
*
* _GetNumVisibleRows
*
* Purpose:
* Returns the number of visible rows according the header
* and (if exist) horizontal scrollbar.
*
* Return value:
* Number of visible rows. If no entire row can be displayed, this
* function will return one.
*/
static unsigned _GetNumVisibleRows(LISTVIEW_Handle hObj, const LISTVIEW_Obj* pObj) {
unsigned RowDistY, ySize, r = 1;
GUI_RECT Rect;
WM_GetInsideRectExScrollbar(hObj, &Rect);
ySize = Rect.y1 - Rect.y0 + 1 - HEADER_GetHeight(pObj->hHeader);
RowDistY = LISTVIEW__GetRowDistY(pObj);
if (RowDistY) {
r = ySize / RowDistY;
r = (r == 0) ? 1 : r;
}
return r;
}
/*********************************************************************
*
* _GetpRow
*/
static LISTVIEW_ROW * _GetpRow(LISTVIEW_Obj * pObj, int Index) {
if (pObj->hSort && (pObj->SortIndex >= 0)) {
LISTVIEW_SORT * pSort;
SORT_TYPE * pData;
pSort = (LISTVIEW_SORT *)GUI_ALLOC_h2p(pObj->hSort);
pData = (SORT_TYPE *)GUI_ALLOC_h2p(pSort->hSortArray);
if (Index >= pSort->SortArrayNumItems) {
return NULL;
}
return (LISTVIEW_ROW *)GUI_ARRAY_GetpItem(&pObj->RowArray, *(pData + Index));
} else {
return (LISTVIEW_ROW *)GUI_ARRAY_GetpItem(&pObj->RowArray, Index);
}
}
/*********************************************************************
*
* _Paint
*/
static void _Paint(LISTVIEW_Handle hObj, LISTVIEW_Obj* pObj, WM_MESSAGE* pMsg) {
const LISTVIEW_ROW* pRow;
GUI_RECT ClipRect, Rect;
int NumRows, NumVisRows, NumColumns;
int LBorder, RBorder, EffectSize;
int xPos, yPos, Width, RowDistY;
int Align, i, j, EndRow;
/* Init some values */
NumColumns = LISTVIEW__GetNumColumns(pObj);
NumRows = LISTVIEW__GetNumRows(pObj);
NumVisRows = _GetNumVisibleRows(hObj, pObj);
RowDistY = LISTVIEW__GetRowDistY(pObj);
LBorder = pObj->LBorder;
RBorder = pObj->RBorder;
EffectSize = pObj->Widget.pEffect->EffectSize;
yPos = HEADER_GetHeight(pObj->hHeader) + EffectSize;
/* 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, &Rect);
GUI__IntersectRect(&ClipRect, &Rect);
/* Set drawing color, font and text mode */
LCD_SetColor(pObj->Props.aTextColor[0]);
GUI_SetFont(pObj->Props.pFont);
GUI_SetTextMode(GUI_TM_TRANS);
/* Sort before drawing, because scroll position may change */
if (pObj->hSort && (pObj->SortIndex >= 0)) {
LISTVIEW_SORT * pSort;
pSort = (LISTVIEW_SORT *)GUI_ALLOC_h2p(pObj->hSort);
if (pSort->fpSort(hObj)) {
return; /* Return on error */
}
}
/* Calculate end row after sorting, because scroll position may have changed */
EndRow = pObj->ScrollStateV.v + (((NumVisRows + 1) > NumRows) ? NumRows : NumVisRows + 1);
/* Do the drawing */
for (i = pObj->ScrollStateV.v; i < EndRow; i++) {
pRow = _GetpRow(pObj, i);
if (pRow) {
Rect.y0 = yPos;
/* Break when all other rows are outside the drawing area */
if (Rect.y0 > ClipRect.y1) {
break;
}
Rect.y1 = yPos + RowDistY - 1;
/* Make sure that we draw only when row is in drawing area */
if (Rect.y1 >= ClipRect.y0) {
int ColorIndex;
/* Set background color */
if (pRow->Disabled) {
ColorIndex = LISTVIEW_CI_DISABLED;
} else if (i == pObj->Sel) {
ColorIndex = (pObj->Widget.State & WIDGET_STATE_FOCUS) ? LISTVIEW_CI_SELFOCUS : LISTVIEW_CI_SEL;
} else {
ColorIndex = LISTVIEW_CI_UNSEL;
}
LCD_SetBkColor(pObj->Props.aBkColor[ColorIndex]);
/* Iterate over all columns */
if (pObj->ShowGrid) {
Rect.y1--;
}
xPos = EffectSize - pObj->ScrollStateH.v;
for (j = 0; j < NumColumns; j++) {
Width = HEADER_GetItemWidth(pObj->hHeader, j);
Rect.x0 = xPos;
/* Break when all other columns are outside the drawing area */
if (Rect.x0 > ClipRect.x1) {
break;
}
Rect.x1 = xPos + Width - 1;
/* Make sure that we draw only when column is in drawing area */
if (Rect.x1 >= ClipRect.x0) {
LISTVIEW_COLUMN* pColumn;
LISTVIEW_CELL* pCell;
pCell = (LISTVIEW_CELL*)GUI_ARRAY_GetpItem(&pRow->CellArray, j);
if (pCell) {
if (pCell->hCellInfo) {
LISTVIEW_CELL_INFO* pCellInfo;
pCellInfo = (LISTVIEW_CELL_INFO*) GUI_ALLOC_h2p(pCell->hCellInfo);
LCD_SetBkColor(pCellInfo->aBkColor[ColorIndex]);
LCD_SetColor(pCellInfo->aTextColor[ColorIndex]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -