⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listview.c

📁 ucgui的3.98版本的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
*********************************************************************************************************
*                                             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 + -