📄 tree.c
字号:
/*
*******************************************************************************
* The real-time kernel "rtCell" *
* Copyright 2005 taowentao, allrights reserved. *
* File : Tree.c *
* By : taowentao 2006-09-02 2007-05-20 *
*******************************************************************************
*/
#if !defined(TREE_H)
#include "giCell\Wins\include\Tree.h"
#endif
/*
*******************************************************************************
* *
*******************************************************************************
*/
static COLOR TreeColor = GD_WHITE;
static COLOR selectColor = GD_BLUE;
static COLOR textColor[2] = {GD_BLACK, GD_WHITE};
/*
*******************************************************************************
* *
*******************************************************************************
*/
static void DrawTreeBmp(TREEITEM *pItem, POINT *pPt)
{
}
static void DrawTree(TREE *pTree, TREEITEM *pItem, POINT *pPt)
{
int x, y, sh;
RECT r;
/* Draw Item */
if (pItem->SubList.pFirst != NULL) {
x = pPt->x-TREE_ITEM_BOX_XOFF; y = pPt->y-TREE_ITEM_BOX_YOFF;
r.left = x; r.top = y;
r.right = r.left+(TREE_ITEM_BOX_XOFF<<1);
r.bottom = r.top+(TREE_ITEM_BOX_YOFF<<1);
DrawRect(&r, GD_DARKGRAY);
DrawHLine(pPt->y, pPt->x-(TREE_ITEM_BOX_XOFF>>1), pPt->x+(TREE_ITEM_BOX_XOFF>>1), GD_BLACK);
if ((pItem->Status & TREE_ITEM_EXPAND) == 0)
DrawVLine(pPt->x, pPt->y-(TREE_ITEM_BOX_YOFF>>1), pPt->y+(TREE_ITEM_BOX_YOFF>>1), GD_BLACK);
DrawDotHLine(pPt->y, r.right+2, r.right+6, GD_DARKGRAY);
DrawDotVLine(pPt->x, r.top-4, r.top-2, GD_DARKGRAY);
if (pItem->Cell.pNext != NULL)
DrawDotVLine(pPt->x, r.bottom+2, r.bottom+4, GD_DARKGRAY);
} else {
DrawDotHLine(pPt->y, pPt->x, pPt->x+10, GD_DARKGRAY);
DrawDotVLine(pPt->x, pPt->y-(TREE_ITEM_BOX_YOFF<<1), pPt->y-2, GD_DARKGRAY);
if (pItem->Cell.pNext != NULL)
DrawDotVLine(pPt->x, pPt->y+2, pPt->y+(TREE_ITEM_BOX_YOFF<<1), GD_DARKGRAY);
}
x = pPt->x+TREE_ITEM_BMP_XOFF+1; y = pPt->y;
if (pItem->Status & TREE_ITEM_BMP) {
DrawTreeBmp(pItem, pPt);
x += TREE_ITEM_STR_XOFF;
} else {
x ++;
}
sh = TextHeight(pItem->Str);
r.left = x; r.top = y-(sh>>1);
r.right = r.left+TextWidth(pItem->Str)-1; r.bottom = r.top+sh;
if (pItem == pTree->ItemSel) {
FillRect(&r, pTree->selectColor);
DrawText(x, r.top, pItem->Str, pTree->textColor[1]);
if (pTree->Status & CTRL_FOCUSSED)
DrawFocusRect(&r, -1, pTree->selectColor);
} else {
DrawText(x, r.top, pItem->Str, pTree->textColor[0]);
}
x = pPt->x;
pPt->x += TREE_ITEM_XOFF; pPt->y += TREE_ITEM_YOFF;
y = pPt->y;
if (pItem->SubList.pFirst != NULL) {
if (pItem->Status & TREE_ITEM_EXPAND) {
CELL *pCell = pItem->SubList.pFirst;
for (; pCell != NULL; pCell = pCell->pNext) {
DrawTree(pTree, TREEITEM_FROM_CELL(pCell), pPt);
}
if (pItem->Cell.pNext != NULL) {
for (; y < pPt->y; y += TREE_ITEM_YOFF) {
DrawDotVLine(x, y-(TREE_ITEM_BOX_YOFF<<1), y+(TREE_ITEM_BOX_YOFF<<1), GD_DARKGRAY);
}
}
}
}
pPt->x -= TREE_ITEM_XOFF;
}
static void TreePaint(VIEW *pView)
{
TREE *pTree;
POINT pt;
RECT r, save = pView->viewRect;
pTree = OBJ_FROM_VIEW(pView);
pt.x = pTree->pView->viewRect.left-pTree->Scrolbar.pHbar->Value+TREE_COFF+TREE_ITEM_XOFF;
pt.y = pTree->pView->viewRect.top-pTree->Scrolbar.pVbar->Value+TREE_COFF+TREE_ITEM_YOFF;
save.left += 2; save.right -= 2; save.top += 2; save.bottom -= 2;
if ((pTree->Status & CTRL_TREE_COMB) == 0) {
r = save;
} else {
r = pView->viewRect;
}
FillRect(&r, pTree->ObjColor);
if (SetPartClipRect(&save) == true) {
if (pTree->pRootItem != NULL)
DrawTree(pTree, pTree->pRootItem, &pt);
RestoreClipRect(&save);
}
if ((pTree->Status & CTRL_TREE_COMB) == 0) {
DrawDownRect(&(pView->viewRect));
}
}
static void TreeSize(TREE *pTree, TREEITEM *pItem, POINT *pPt)
{
int xSize = pPt->x + gdTextWidth(pItem->Str) + 32;
if (pTree->xSize < xSize) pTree->xSize = xSize;
pTree->ySize += TREE_ITEM_YOFF;
pPt->x += TREE_ITEM_XOFF; pPt->y += TREE_ITEM_YOFF;
if (pItem->SubList.pFirst != NULL) {
if (pItem->Status & TREE_ITEM_EXPAND) {
CELL *pCell = pItem->SubList.pFirst;
for (; pCell != NULL; pCell = pCell->pNext) {
TreeSize(pTree, TREEITEM_FROM_CELL(pCell), pPt);
}
}
}
pPt->x -= TREE_ITEM_XOFF;
}
static void SetTreeScrollBar(TREE *pTree)
{
int off = (pTree->Status & CTRL_TREE_COMB)? 0 : 2;
POINT pt;
pt.x = TREE_ITEM_XOFF; pt.y = TREE_ITEM_YOFF;
pTree->xSize = 0;
pTree->ySize = 0;
if (pTree->pRootItem != NULL) {
TreeSize(pTree, pTree->pRootItem, &pt);
pTree->xSize += (TREE_COFF<<1); pTree->ySize += TREE_ITEM_YOFF+(TREE_COFF<<1);
}
SetScrollBars(pTree->pView, &(pTree->Scrolbar), pTree->xSize, pTree->ySize, off);
UpdateView(pTree->pView);
}
static CBOOL TreeFindItem(TREEITEM *pFirstItem, TREEITEM *pItem)
{
if (pFirstItem == pItem) return (true);
if (pFirstItem->SubList.pFirst != NULL) {
CELL *pCell = pFirstItem->SubList.pFirst;
int res;
for (; pCell != NULL; pCell = pCell->pNext) {
res = TreeFindItem(TREEITEM_FROM_CELL(pCell), pItem);
if (res == true) return (res);
}
}
return (false);
}
static CBOOL FindParentItem(TREEITEM *pParent, TREEITEM *pItem)
{
if (pItem == NULL) return (false);
for (pItem = pItem->pParent; pItem != NULL; pItem = pItem->pParent) {
if (pParent == pItem) return (true);
}
return (false);
}
static TREEITEM * FindNextItem(TREE *pTree, TREEITEM *pItem)
{
if (pTree->pRootItem != NULL) {
if (TreeFindItem(pTree->pRootItem, pItem) == true) {
TREEITEM *pParent;
if (pItem->SubList.pFirst != NULL) {
if ((pItem->Status & TREE_ITEM_EXPAND) != 0) {
return (TREEITEM_FROM_CELL(pItem->SubList.pFirst));
}
}
for (pParent = pItem; pParent != NULL; pParent = pParent->pParent) {
CELL *pCell = pParent->Cell.pNext;
if (pCell != NULL) {
return (TREEITEM_FROM_CELL(pCell));
}
}
}
}
return (NULL);
}
static TREEITEM * FindPrevItem(TREE *pTree, TREEITEM *pItem)
{
if (pTree->pRootItem != NULL) {
if (TreeFindItem(pTree->pRootItem, pItem) == true) {
TREEITEM *pParent = pItem->pParent;
if (pParent == NULL) return (NULL);
if (pItem->Cell.ppPrev != &(pParent->SubList.pFirst)) {
TREEITEM *pPrev = TREEITEM_FROM_CELL(PREV_CELL(&(pItem->Cell)));
while (pPrev->SubList.pFirst != NULL) {
if ((pPrev->Status & TREE_ITEM_EXPAND) != 0) {
pPrev = (TREEITEM_FROM_CELL(LIST_LAST_CELL(&(pPrev->SubList))));
} else {
return (pPrev);
}
}
return (pPrev);
} else {
return (pParent);
}
}
}
return (NULL);
}
static int GetTreeItem(TREE *pTree, TREEITEM *pItem, POINT *pPt, POINT *pPos)
{
if ((pPt->y-(TREE_ITEM_YOFF>>1)) < pPos->y &&
(pPt->y+(TREE_ITEM_YOFF>>1)) > pPos->y) {
RECT r;
r.left = pPt->x-(TREE_ITEM_BOX_XOFF<<1);
r.top = pPt->y-(TREE_ITEM_BOX_YOFF<<1);
r.right = r.left+(TREE_ITEM_BOX_XOFF<<2);
r.bottom = r.top+(TREE_ITEM_BOX_YOFF<<2);
if (IsInRect(pPos->x, pPos->y, &r) == true) {
if (pItem->Status & TREE_ITEM_EXPAND) {
pItem->Status &= ~TREE_ITEM_EXPAND;
if (FindParentItem(pItem, pTree->ItemSel) == true)
pTree->ItemSel = pItem;
} else {
pItem->Status |= TREE_ITEM_EXPAND;
}
return (true);
} else {
pTree->ItemSel = pItem;
return (false);
}
}
pPt->x += TREE_ITEM_XOFF; pPt->y += TREE_ITEM_YOFF;
if (pItem->SubList.pFirst != NULL) {
if (pItem->Status & TREE_ITEM_EXPAND) {
CELL *pCell = pItem->SubList.pFirst;
int res;
for (; pCell != NULL; pCell = pCell->pNext) {
res = GetTreeItem(pTree, TREEITEM_FROM_CELL(pCell), pPt, pPos);
if (res == true || res == false) return (res);
}
}
}
pPt->x -= TREE_ITEM_XOFF;
return (-1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -