bgfeditview.cpp
来自「用bcg库编写的java IDE 源码」· C++ 代码 · 共 553 行
CPP
553 行
// BGFEditView.cpp: implementation of the CBGFEditView class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BGFEditView.h"
#include "editcmd.h"
#include "BaseTextBuffer.h"
#include "browser.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define REAL_MARGIN_WIDTH 20
#define GetColapseWidth() m_bEnableColapsingCode?GetLineHeight():0
#define RealMarginWidth() m_bSelMargin?REAL_MARGIN_WIDTH:0
#define COOKIE_SLOT 0x0
#define DATA_SLOT 0x1
#define COOKIE_COLAPSED 0x0100
static LPTSTR s_apszKeywordList[] =
{
_T ("abstract"),
_T ("default"),
_T ("goto"),
_T ("null"),
_T ("synchronized"),
_T ("boolean"),
_T ("do"),
_T ("if"),
_T ("package"),
_T ("this"),
_T ("break"),
_T ("double"),
_T ("implements"),
_T ("private"),
_T ("threadsafe"),
_T ("byte"),
_T ("else"),
_T ("import"),
_T ("protected"),
_T ("throw"),
_T ("byvalue"),
_T ("extends"),
_T ("instanceof"),
_T ("public"),
_T ("transient"),
_T ("case"),
_T ("false"),
_T ("int"),
_T ("return"),
_T ("true"),
_T ("catch"),
_T ("final"),
_T ("interface"),
_T ("short"),
_T ("try"),
_T ("char"),
_T ("finally"),
_T ("long"),
_T ("static"),
_T ("void"),
_T ("class"),
_T ("float"),
_T ("native"),
_T ("super"),
_T ("while"),
_T ("const"),
_T ("for"),
_T ("new"),
_T ("switch"),
_T ("continue"),
NULL
};
static BOOL IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength)
{
for (int L = 0; apszKeywords[L] != NULL; L++)
{
if (_tcsncmp (apszKeywords[L], pszChars, nLength) == 0
&& apszKeywords[L][nLength] == 0)
return TRUE;
}
return FALSE;
}
static BOOL IsKeyword (LPCTSTR pszChars, int nLength)
{
return IsXKeyword (s_apszKeywordList, pszChars, nLength);
}
static BOOL IsNumber (LPCTSTR pszChars, int nLength)
{
if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x')
{
for (int I = 2; I < nLength; I++)
{
if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') ||
(pszChars[I] >= 'a' && pszChars[I] <= 'f'))
continue;
return FALSE;
}
return TRUE;
}
if (!_istdigit (pszChars[0]))
return FALSE;
for (int I = 1; I < nLength; I++)
{
if (!_istdigit (pszChars[I]) && pszChars[I] != '+' &&
pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' &&
pszChars[I] != 'E')
return FALSE;
}
return TRUE;
}
#define DEFINE_BLOCK(pos, colorindex) \
ASSERT((pos) >= 0 && (pos) <= nLength);\
if (pBuf != NULL)\
{\
if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\
pBuf[nActualItems].m_nCharPos = (pos);\
pBuf[nActualItems].m_nColorIndex = (colorindex);\
nActualItems ++;}\
}
#define COOKIE_COMMENT 0x0001
#define COOKIE_PREPROCESSOR 0x0002
#define COOKIE_EXT_COMMENT 0x0004
#define COOKIE_STRING 0x0008
#define COOKIE_CHAR 0x0010
#define COOKIE_WIZARD_CODE 0x0020
#define COOKIE_COLAPSIBLE 0x0040
#define COOKIE_ROOTNODE 0x0080
#define COOKIE_COLAPSED 0x0100
bool isopenbrace (TCHAR c)
{
return c == _T ('{') || c == _T ('(') || c == _T ('[') || c == _T ('<');
}
bool isclosebrace (TCHAR c)
{
return c == _T ('}') || c == _T ('}') || c == _T (']') || c == _T ('>');
}
bool isopenbrace (LPCTSTR s)
{
return s[1] == _T ('\0') && isopenbrace (*s);
}
bool isclosebrace (LPCTSTR s)
{
return s[1] == _T ('\0') && isclosebrace (*s);
}
int bracetype (TCHAR c)
{
static LPCTSTR braces = _T("{}()[]<>");
LPCTSTR pos = _tcschr (braces, c);
return pos ? pos - braces + 1 : 0;
}
int bracetype (LPCTSTR s)
{
if (s[1])
return 0;
return bracetype (*s);
}
IMPLEMENT_DYNCREATE(CBGFEditView,CCrystalEditViewEx)
BEGIN_MESSAGE_MAP (CBGFEditView,CCrystalEditViewEx)
ON_WM_SETCURSOR()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()
CBGFEditView::CBGFEditView()
{
m_bEnableColapsingCode = FALSE;
}
CBGFEditView::~CBGFEditView()
{
}
void CBGFEditView::DrawColapseIndentImpl(CDC * pdc, const CRect & rect,
int nLineIndex,int nChar,BOOL bNode,BOOL bRootNode)
{
CRect rcFill(rect);
if(bNode)
{
int nOffSet = 0;
CRect rcRect(rect);
if(!bRootNode)
{
nOffSet = nChar*GetCharWidth();
rcFill.OffsetRect(nOffSet,0);
rcRect.OffsetRect(nOffSet,0);
}
int nShrink = (GetLineHeight()/2)-5;
rcFill.DeflateRect(nShrink,nShrink,nShrink,nShrink);
pdc->Draw3dRect(rcFill,GetSysColor(COLOR_BTNSHADOW),
GetSysColor(COLOR_BTNSHADOW));
CPen nPen(PS_SOLID,1,GetSysColor(COLOR_BTNSHADOW));
int nMid = GetLineHeight()/2;
CPen* pOldPen = pdc->SelectObject(&nPen);
CBaseTextBuffer* pTemp = (CBaseTextBuffer*)m_pTextBuffer;
//************
//draw plus
if(pTemp->isColapsed(nLineIndex,nChar))
{
pdc->MoveTo(rcRect.left+nMid,rcRect.top+nShrink+3);
pdc->LineTo(rcRect.left+nMid,rcRect.bottom-nShrink-3);
}
//************/
pdc->MoveTo(rcRect.left+nShrink+3,rcRect.top+nMid);
pdc->LineTo(rcRect.right-nShrink-3,rcRect.top+nMid);
//fill gap up and down for shrink
rcRect.OffsetRect(-nOffSet,0);//reverse
BOOL bRt = bRootNode;
pdc->MoveTo(rcRect.left+nMid,rcRect.top);
pdc->LineTo(rcRect.left+nMid,bRt?rcRect.top+nShrink:rcRect.top+nMid+1);
pdc->MoveTo(rcRect.left+nMid,bRt?rcRect.bottom-nShrink:rcRect.bottom-nMid);
pdc->LineTo(rcRect.left+nMid,rcRect.bottom);
pdc->SelectObject(pOldPen);
if(bRootNode)//draw line from node to '{' or
{
LPCTSTR lszpChar = GetLineChars(nLineIndex);
int nLength = GetLineLength(nLineIndex);
for(int I=0; I<nLength; I++)
{
if(iswspace(lszpChar[I]))
continue;
else break;
}
int nOffSet = I*GetCharWidth();
CPen nPen_1(PS_DASH,1,GetSysColor(COLOR_BTNSHADOW));
CPen *pOldPen = pdc->SelectObject(&nPen_1);
pdc->MoveTo(rcFill.right,rcRect.top+nMid);
pdc->LineTo(rcFill.right+nOffSet,rcRect.top+nMid);
pdc->SelectObject(pOldPen);
}
}
else
{
int nShrink = (GetLineHeight()/2);
rcFill.DeflateRect(nShrink,0,nShrink,0);
pdc->FillSolidRect(rcFill,GetSysColor(COLOR_BTNSHADOW));
}
}
void CBGFEditView::DrawColapseIndent(CDC * pdc, const CRect & rect,
int nLineIndex)
{
if(!m_bEnableColapsingCode||nLineIndex == -1)
{
pdc->FillSolidRect(rect,GetColor(COLORINDEX_BKGND));
if(m_bEnableColapsingCode)
DrawColapseIndentImpl(pdc,rect,nLineIndex,-1,FALSE,FALSE);
return;
}
pdc->FillSolidRect(rect,GetColor(COLORINDEX_BKGND));
LPCTSTR lszpChar = GetLineChars(nLineIndex);
bool bChecked4RootNode = false;
CBaseTextBuffer* pTemp = (CBaseTextBuffer*)m_pTextBuffer;
int nodeCount = pTemp->nodeCount(nLineIndex);
for(int I=0; I<nodeCount; I++)
{
int nCurIndex = pTemp->nodeIndexAt(nLineIndex,I);
if(!bChecked4RootNode&&(pTemp->nodeDeclAt(nLineIndex,I)->getParent() == NULL))
{
bChecked4RootNode = true;
if((nCurIndex>0&&iswspace(lszpChar[nCurIndex-1]))||nCurIndex==0)//only draw box if there is space
DrawColapseIndentImpl(pdc,rect,nLineIndex,nCurIndex,TRUE,TRUE);
}
else
if(m_bEnableColapsingAllBlocks)
{
if((nCurIndex>0&&iswspace(lszpChar[nCurIndex-1]))||nCurIndex==0)//only draw box if there is space
DrawColapseIndentImpl(pdc,rect,nLineIndex,nCurIndex,TRUE,FALSE);
}
else return;
}
if(nodeCount == 0)
DrawColapseIndentImpl(pdc,rect,nLineIndex,-1,FALSE,FALSE);
}
void CBGFEditView::GetLineRect(int nLineIndex,CRect &rcLine)
{
int nScreenLine = nLineIndex-m_nTopLine;
CRect rcClient;
GetClientRect (rcClient);
int nLineHeight = GetLineHeight();
int nOffSet = nScreenLine* nLineHeight;
rcLine.top = rcClient.top+nOffSet;
rcLine.bottom = rcLine.top+nLineHeight;
rcLine.left = GetMarginWidth();
rcLine.right = rcClient.right;
}
CRect CBGFEditView::GetExpandNode(CPoint pt,int &nNodeIndex)
{
// /**
CPoint ptText = ClientToText(pt);
int nLineIndex = ptText.y;
CRect rcRect;
GetLineRect(nLineIndex,rcRect);
CRect rcColapseIndent((RealMarginWidth()),0,(RealMarginWidth())+(GetColapseWidth()),rcRect.bottom);
rcRect = rcColapseIndent;
BOOL bRootNode = FALSE;
int nShrink = (GetLineHeight()/2)-5;
rcRect.DeflateRect(nShrink,nShrink,nShrink,nShrink);
CBaseTextBuffer* pTemp = (CBaseTextBuffer*)m_pTextBuffer;
int nNodeCount = pTemp->nodeCount(nLineIndex);
for(int xI=0; xI<nNodeCount; xI++)
{
int nCurIndex = pTemp->nodeIndexAt(nLineIndex,xI);
if(xI==0&&pTemp->m_pDeclManager->PointInBlockDecl
(nCurIndex,nLineIndex,bRootNode)&&bRootNode)
{
if(bRootNode)//test at the margin
{
if(rcRect.PtInRect(pt))
{
nNodeIndex = nCurIndex;
return rcRect;
}
}
else
goto non_root;
}
else
{
non_root:
int nOffSet = nCurIndex*GetCharWidth();
rcRect.OffsetRect(nOffSet,0);
if(rcRect.PtInRect(pt))
{
nNodeIndex = nCurIndex;
return rcRect;
}
else
rcRect.OffsetRect(-nOffSet,0);
}
}
// **/
return CRect(0,0,0,0);
}
int CBGFEditView::GetMarginWidth()
{
return CCrystalEditViewEx::GetMarginWidth();
if(m_bSelMargin)
return ((REAL_MARGIN_WIDTH)+(GetColapseWidth()));
else
return GetColapseWidth();
}
void CBGFEditView::OnDraw(CDC * pdc)
{
CCrystalEditViewEx::OnDraw(pdc);return;
CRect rcClient;
GetClientRect (rcClient);
int nLineCount = GetLineCount();
int nLineHeight = GetLineHeight();
PrepareSelBounds();
CDC cacheDC;
VERIFY(cacheDC.CreateCompatibleDC(pdc));
if(m_pCacheBitmap == NULL)
{
m_pCacheBitmap = new CBitmap;
VERIFY(m_pCacheBitmap->CreateCompatibleBitmap(pdc,rcClient.Width(),rcClient.Height()));
}
CBitmap *pOldBitmap = cacheDC.SelectObject(m_pCacheBitmap);
CRect rcLine;
rcLine = rcClient;
rcLine.bottom = rcLine.top + nLineHeight;
int margin = GetMarginWidth();
CRect rcCacheMargin(0,0,(RealMarginWidth()),nLineHeight);
CRect rcColapseIndent((RealMarginWidth()),0,(RealMarginWidth())+(GetColapseWidth()),nLineHeight);
CRect rcCacheLine(GetMarginWidth(),0,GetMarginWidth()+rcLine.Width(),nLineHeight);
//rcLine.left = rcCacheLine.left;
//rcLine.right = rcCacheLine.right;
int nBreaks;
int nMaxLineChars = GetScreenChars();
int nCurrentLine = m_nTopLine;
while(rcLine.top < rcClient.bottom)
{
nBreaks = 0;
rcLine.bottom = rcLine.top + (nBreaks + 1) * nLineHeight;
rcCacheLine.bottom = rcCacheLine.top + rcLine.Height();
rcCacheMargin.bottom = rcCacheMargin.top + rcLine.Height();
rcColapseIndent.bottom = rcColapseIndent.top + rcLine.Height();
if(rcCacheLine.top < 0 )
rcLine.bottom+= rcCacheLine.top;
if(nCurrentLine < nLineCount)
{
DrawMargin (&cacheDC, rcCacheMargin, nCurrentLine);
DrawSingleLine(&cacheDC, rcCacheLine, nCurrentLine);
DrawColapseIndent(&cacheDC,rcColapseIndent,nCurrentLine);
}
else
{
DrawMargin(&cacheDC, rcCacheMargin, -1);
DrawSingleLine(&cacheDC, rcCacheLine, -1);
DrawColapseIndent(&cacheDC,rcColapseIndent,-1);
}
VERIFY(pdc->BitBlt(rcLine.left,rcLine.top,rcLine.Width(),rcLine.Height(),&cacheDC, 0, 0, SRCCOPY));
rcLine.top = rcLine.bottom;
rcCacheLine.top = 0;
rcCacheMargin.top = 0;
rcColapseIndent.top = 0;
nCurrentLine++;
}
cacheDC.SelectObject (pOldBitmap);
cacheDC.DeleteDC ();
}
BOOL CBGFEditView::OnSetCursor (CWnd * pWnd, UINT nHitTest, UINT message)
{
if(!CCrystalTextView::OnSetCursor(pWnd,nHitTest,message))
return FALSE;
if(nHitTest == HTCLIENT)
{
CPoint pt;
::GetCursorPos(&pt);
ScreenToClient(&pt);
int nNodeIndex = -1;
if(pt.x < GetMarginWidth()||GetExpandNode(pt,nNodeIndex).PtInRect(pt))
{
::SetCursor(::LoadCursor(GetResourceHandle(),MAKEINTRESOURCE(IDR_MARGIN_CURSOR)));
}
return TRUE;
}
return TRUE;
}
void CBGFEditView::OnLButtonDblClk (UINT nFlags, CPoint point)
{
CCrystalTextView::OnLButtonDblClk (nFlags, point);
if(!m_bDragSelection)
{
int nNodeIndex = -1;
CRect rcNode = GetExpandNode(point,nNodeIndex);
if(rcNode.PtInRect(point))
{
CPoint ptLine = ClientToText(point);
CBaseTextBuffer* pTemp = (CBaseTextBuffer*)m_pTextBuffer;
pTemp->_toggle(ptLine.y,nNodeIndex,this);
//InvalidateRect(&rcNode);
//UpdateWindow();
}
}
}
void CBGFEditView::OnLButtonDown (UINT nFlags, CPoint point)
{
int nNodeIndex = -1;
CRect rcNode = GetExpandNode(point,nNodeIndex);
if(rcNode.PtInRect(point))
{
CPoint ptLine = ClientToText(point);
CBaseTextBuffer* pBaseTB = (CBaseTextBuffer*)m_pTextBuffer;
pBaseTB->_toggle(ptLine.y,nNodeIndex,this);
/*
CRect rcClient;
GetClientRect(rcClient);
rcClient.top = rcNode.top;
InvalidateRect(&rcClient);
UpdateWindow();
*/
}
else CCrystalTextView::OnLButtonDown (nFlags, point);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?