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

📄 listview.c

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