1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
40 //M*/// HawkView.cpp : implementation of the CHawkView class
64 static char THIS_FILE[] = __FILE__;
67 // Foward declarations of functions included in this code module:
68 LRESULT CALLBACK GoToLineProc(HWND, UINT, WPARAM, LPARAM);
69 HGDIOBJ CreateDIB( int width, int height, HDC dc );
71 /////////////////////////////////////////////////////////////////////////////
74 IMPLEMENT_DYNCREATE(CHawkView, CEditView)
76 BEGIN_MESSAGE_MAP(CHawkView, CEditView)
77 //{{AFX_MSG_MAP(CHawkView)
82 ON_CONTROL_REFLECT(EN_CHANGE, OnChange)
83 ON_WM_CTLCOLOR_REFLECT()
84 ON_COMMAND(ID_UNTAB, OnUntab)
85 ON_COMMAND(ID_GO_HOME, OnGoHome)
86 ON_COMMAND(ID_GOTO_LINE, OnGotoLine)
89 // Standard printing commands
90 ON_COMMAND(ID_FILE_PRINT, CEditView::OnFilePrint)
91 ON_COMMAND(ID_FILE_PRINT_DIRECT, CEditView::OnFilePrint)
92 ON_COMMAND(ID_FILE_PRINT_PREVIEW, CEditView::OnFilePrintPreview)
95 /////////////////////////////////////////////////////////////////////////////
96 // CHawkView construction/destruction
98 int CHawkView::m_instanceCount = 0;
99 HFONT CHawkView::hFont = NULL;
100 HDC CHawkView::hMemDC = NULL;
101 HGDIOBJ CHawkView::hOldBmp = NULL;
102 ColorScheme CHawkView::Scheme;
104 CHawkView::CHawkView() : m_edit(GetEditCtrl()), MaxTextBuffer(1 << 17),
105 LINE_BUF_SIZE(1000), TAB_SIZE(4)
107 Line = new char[LINE_BUF_SIZE];
108 Space = new char[LINE_BUF_SIZE];
111 maxTokens = (1 << 17)/sizeof(Token);
112 Tokens = (Token*)malloc( maxTokens * sizeof(Token) );
113 TextBuffer = (char*)malloc( MaxTextBuffer );
119 CHawkApp* app = (CHawkApp*)AfxGetApp();
121 Scheme.background = app->GetProfileInt("Configuration", "background", RGB(222,220,200));
122 Scheme.clr[TOKEN_NORMAL] = app->GetProfileInt("Configuration", "TOKEN_NORMAL", RGB(0,0,0));
123 Scheme.clr[TOKEN_KEYWORD] = app->GetProfileInt("Configuration", "TOKEN_KEYWORD", RGB(0,0,150));
124 Scheme.clr[TOKEN_COMMENT] = app->GetProfileInt("Configuration", "TOKEN_COMMENT", RGB(130,130,130));
125 Scheme.clr[TOKEN_NUMBER] = app->GetProfileInt("Configuration", "TOKEN_NUMBER", RGB(150,100,0));
126 Scheme.clr[TOKEN_STRING] = app->GetProfileInt("Configuration", "TOKEN_STRING", RGB(150,0,100));
127 Scheme.selbk = app->GetProfileInt("Configuration", "selbk", RGB(150,150,150));
128 Scheme.selfk = app->GetProfileInt("Configuration", "selfk", RGB(0,0,0));
129 Scheme.bkBrush = (HBRUSH)CreateSolidBrush( Scheme.background );
130 hFont = CreateFont( 0, // Height
134 FW_NORMAL, // Boldness
142 DEFAULT_PITCH | FF_MODERN,
144 hMemDC = CreateCompatibleDC( 0 );
145 hOldBmp = CreateDIB( GetSystemMetrics( SM_CXSCREEN ),
146 GetSystemMetrics( SM_CYSCREEN ), hMemDC );
147 SelectObject( hMemDC, hFont );
154 CHawkView::~CHawkView()
156 ASSERT(m_instanceCount > 0);
160 DeleteObject( SelectObject( hMemDC, hOldBmp ));
162 DeleteObject( hFont );
173 BOOL CHawkView::Customize()
176 SetWindowFont( hEdit, hFont, 0 );
177 int tab_size = TAB_SIZE * 4;
178 Edit_SetTabStops( hEdit, 1, &tab_size );
179 Edit_LimitText( hEdit, 0xffff );
180 Edit_FmtLines( hEdit, 1 );
184 BOOL CHawkView::PreCreateWindow(CREATESTRUCT& cs)
186 // TODO: Modify the Window class or styles here by modifying
187 // the CREATESTRUCT cs
189 return CEditView::PreCreateWindow(cs);
192 /////////////////////////////////////////////////////////////////////////////
194 void CHawkView::OnDraw(CDC* pDC)
196 CHawkDoc* pDoc = GetDocument();
198 // TODO: add draw code for native data here
201 /////////////////////////////////////////////////////////////////////////////
202 // CHawkView printing
204 BOOL CHawkView::OnPreparePrinting(CPrintInfo* pInfo)
206 // default preparation
207 return DoPreparePrinting(pInfo);
210 void CHawkView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
212 // TODO: add extra initialization before printing
215 void CHawkView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
217 // TODO: add cleanup after printing
220 /////////////////////////////////////////////////////////////////////////////
221 // CHawkView diagnostics
224 void CHawkView::AssertValid() const
226 CEditView::AssertValid();
229 void CHawkView::Dump(CDumpContext& dc) const
234 CHawkDoc* CHawkView::GetDocument() // non-debug version is inline
236 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CHawkDoc)));
237 return (CHawkDoc*)m_pDocument;
241 /////////////////////////////////////////////////////////////////////////////
242 // CHawkView message handlers
244 int CHawkView::OnCreate(LPCREATESTRUCT lpCreateStruct)
246 if (CEditView::OnCreate(lpCreateStruct) == -1)
253 CString CHawkView::GetText()
255 int length = GetBufferLength() + 1;
256 char* buffer = new char[length];
257 m_edit.GetWindowText(buffer, length);
258 CString text = CString(buffer);
263 void CHawkView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
265 CEditView::OnKeyDown(nChar, nRepCnt, nFlags);
269 void CHawkView::UpdateCursorPos()
271 CStatusBar* pBar = ((CMainFrame*)AfxGetMainWnd())->GetStatusBar();
273 POINT pt = GetCursorPos();
274 str.Format("%d", pt.x + 1);
275 pBar->SetPaneText(1, LPCTSTR(str));
276 str.Format("%d", pt.y + 1);
277 pBar->SetPaneText(2, LPCTSTR(str));
279 SetTimer(1, 500, 0); // Update the syntax tip
282 void CHawkView::OnLButtonDown(UINT nFlags, CPoint point)
286 CEditView::OnLButtonDown(nFlags, point);
289 void CHawkView::OnContextMenu(CWnd* pWnd, CPoint point)
291 CHawkApp* pApp = (CHawkApp*)AfxGetApp();
292 CMenu* pMenu = pApp->GetContextMenu();
294 pMenu->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, pWnd);
297 BOOL CHawkView::OnCommand(WPARAM wParam, LPARAM lParam)
301 int index = HIWORD(wParam) - 1;
302 CHawkApp* pApp = (CHawkApp*)AfxGetApp();
303 CFuncDialog* pDlg = pApp->GetFuncDialog(index);
304 pDlg->SetItems(pApp->GetFunctions(index));
305 if(pDlg->DoModal() == IDOK)
307 CString str = pDlg->GetCurrentItem();
309 m_edit.GetSel(p1, p2);
310 m_edit.ReplaceSel(LPCTSTR(str), TRUE);
314 return CEditView::OnCommand(wParam, lParam);
317 LRESULT CHawkView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
328 code = CEditView::WindowProc( message, wParam, lParam);
329 ::GetCaretPos( &pt );
331 GetTextExtentPoint32( hMemDC, "A", 1, &sz );
332 ::CreateCaret( hEdit, 0, 2, sz.cy );
333 ::SetCaretPos( pt.x, pt.y );
334 ::ShowCaret( hEdit );
338 if( (TCHAR)wParam == '\t' )
340 DWORD sel = Edit_GetSel(hEdit);
341 int sel_start = LOWORD( sel );
342 int sel_end = HIWORD( sel );
344 if( sel_start != sel_end )
346 int i, line_start, line_end;
349 if( sel_start > sel_end )
356 line_start = Edit_LineFromChar( hEdit, sel_start );
357 line_end = Edit_LineFromChar( hEdit, sel_end );
358 line_end += Edit_LineIndex( hEdit, line_end ) < sel_end;
360 for( i = line_start; i < line_end; i++ )
362 int idx = Edit_LineIndex( hEdit, i );
363 Space[TAB_SIZE] = '\0';
364 Edit_SetSel( hEdit, idx, idx );
365 Edit_ReplaceSel( hEdit, Space );
366 Space[TAB_SIZE] = ' ';
368 Edit_SetSel( hEdit, sel_start, sel_end + (line_end - line_start)*TAB_SIZE );
370 RenderHighlightedText(TRUE);
375 code = CEditView::WindowProc( message, wParam, lParam);
376 if( (TCHAR)wParam == '\r' || (TCHAR)wParam == '\t' )
378 DWORD sel = Edit_GetSel(hEdit);
379 int sel_start = LOWORD( sel );
380 int sel_end = HIWORD( sel );
381 if( sel_start == sel_end )
383 int line = Edit_LineFromChar( hEdit, sel_end ), cnt = 0;
386 if( (TCHAR)wParam == '\r' && line > 0 )
389 int line_len = Edit_GetLine( hEdit, line - 1, Line, LINE_BUF_SIZE );
390 Line[line_len] = '\0';
391 while( isspace( Line[pos] ))
393 cnt = Line[pos] == '\t' ? ((cnt + TAB_SIZE) & -TAB_SIZE) : cnt + 1;
397 else if( (TCHAR)wParam == '\t' )
399 cnt = ((pt.x + TAB_SIZE) & -TAB_SIZE) - pt.x;
400 Edit_SetSel( hEdit, sel_end-1, sel_end );
401 Edit_ReplaceSel( hEdit, "");
407 ::SendMessage( hEdit, EM_REPLACESEL, 1L, (LPARAM)Space );
411 RenderHighlightedText( TRUE );
419 DWORD sel = Edit_GetSel( hEdit );
420 int line0 = Edit_GetFirstVisibleLine( hEdit );
421 int sel_start0 = LOWORD( sel );
422 int sel_end0 = HIWORD( sel );
423 if( wParam == VK_HOME && sel_start0 == sel_end0 )
425 int line_start = Edit_LineFromChar( hEdit, sel_start0 );
427 Edit_GetLine( hEdit, line_start, Line, LINE_BUF_SIZE );
428 line_start = Edit_LineIndex( hEdit, line_start );
429 while( isspace(Line[pos])) pos++;
430 if( line_start + pos != sel_start0 )
432 Edit_SetSel( hEdit, line_start + pos, line_start + pos );
436 Edit_SetSel( hEdit, line_start, line_start );
438 Edit_ScrollCaret( hEdit );
442 code = CEditView::WindowProc( message, wParam, lParam);
443 sel = Edit_GetSel( hEdit );
444 int sel_start1 = LOWORD( sel );
445 int sel_end1 = HIWORD( sel );
447 if( ((int)wParam == VK_PRIOR || (int)wParam == VK_NEXT) &&
448 Edit_GetFirstVisibleLine( hEdit ) == line0 )
450 int new_pos = wParam == VK_PRIOR ? 0 : ::Edit_GetTextLength( hEdit );
451 if( sel_start1 != sel_end1 )
453 if( (int)wParam == VK_PRIOR )
454 sel_start1 = new_pos;
460 sel_start1 = sel_end1 = new_pos;
463 Edit_SetSel( hEdit, sel_start1, sel_end1 );
464 Edit_ScrollCaret( hEdit );
467 if( (sel_start0 != sel_start1 || sel_end0 != sel_end1) &&
468 abs(sel_end0 - sel_start0) + abs(sel_end1 - sel_start1) > 0)
470 RenderHighlightedText();
478 DWORD sel = Edit_GetSel( hEdit );
479 int sel_start0 = LOWORD( sel );
480 int sel_end0 = HIWORD( sel );
481 code = CEditView::WindowProc( message, wParam, lParam);
482 sel = Edit_GetSel( hEdit );
483 int sel_start1 = LOWORD( sel );
484 int sel_end1 = HIWORD( sel );
485 if( sel_start0 != sel_start1 || sel_end0 != sel_end1 )
487 RenderHighlightedText();
493 code = CEditView::WindowProc( message, wParam, lParam);
494 RenderHighlightedText();
499 RenderHighlightedText();
503 return CEditView::WindowProc(message, wParam, lParam);
508 //LRESULT CALLBACK GoToLineProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
513 // case WM_INITDIALOG:
515 // int upper = Edit_GetLineCount( hEdit );
516 // SendDlgItemMessage( hDlg, IDC_LINESPIN, UDM_SETRANGE, 0, MAKELONG( upper, 1));
517 // Edit_SetSel( GetDlgItem( hDlg, IDC_LINETEXT ), 0, -1 );
518 // SetFocus( GetDlgItem( hDlg, IDC_LINETEXT ));
522 // if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
524 // int val = GetDlgItemInt( hDlg, IDC_LINETEXT, 0, 0 );
525 // EndDialog(hDlg, LOWORD(val));
534 HGDIOBJ CreateDIB( int width, int height, HDC dc )
540 memset( &bmi.bmiHeader, 0, sizeof(bmi.bmiHeader));
542 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
543 bmi.bmiHeader.biWidth = width;
544 bmi.bmiHeader.biHeight = height;
545 bmi.bmiHeader.biPlanes = 1;
546 bmi.bmiHeader.biBitCount = 16;
547 bmi.bmiHeader.biCompression = BI_RGB;
549 hbmp = CreateDIBSection( dc, &bmi, DIB_RGB_COLORS, &data, 0, 0 );
550 return SelectObject( dc, hbmp );
554 int CHawkView::ScanTextBuffer( char* text, Token* tokens, int max_tokens )
557 Token prev_token, token;
558 Token* tokens0 = tokens;
562 InitLexer( &lexer, text );
563 GetToken( &lexer, &prev_token );
568 GetToken( &lexer, &token );
569 if( token.type != prev_token.type )
571 *tokens++ = prev_token;
574 if( token.type == TOKEN_END ) break;
576 return tokens - tokens0;
579 void CHawkView::RenderHighlightedText( BOOL update )
582 HDC hScreenDC = ::GetDC(hEdit);
586 char* text = TextBuffer;
587 int fst_char, fst_line;
589 int cChars = ::Edit_GetTextLength( hEdit );
591 ColorScheme* scheme = &Scheme;
593 if( Disable_Update ) return;
595 memset( Space, ' ', LINE_BUF_SIZE );
600 cChars = ::GetWindowText( hEdit, text, 0xffff );
601 cTokens = ScanTextBuffer( text, Tokens, maxTokens );
603 fst_line = Edit_GetFirstVisibleLine( hEdit );
604 fst_char = Edit_LineIndex( hEdit, fst_line );
607 if( Tokens[t].start < fst_char || cTokens < 2 )
610 while( right - t > 1 )
612 int m = (right + t)>>1;
613 if( Tokens[m].start <= fst_char )
620 ::GetCaretPos( &pt );
621 ::HideCaret( hEdit );
622 ::GetClientRect( hEdit, &rect );
623 FillRect( hMemDC, &rect, scheme->bkBrush );
624 GetTextExtentPoint32( hMemDC, "A", 1, &size );
625 SetBkColor( hMemDC, scheme->background );
627 if( cChars > 0 && cTokens > 0 && t < cTokens )
629 int lines = (rect.bottom + size.cy - 1)/(size.cy > 1 ? size.cy : 1);
632 int line_start = fst_char;
633 DWORD sel = Edit_GetSel( hEdit );
634 int sel_start = LOWORD( sel );
635 int sel_end = HIWORD( sel );
636 offset = GetScrollPos( SB_HORZ );
638 ::SetTextColor( hMemDC, Scheme.clr[Tokens[t].type]);
643 int end_pos = t+1 < cTokens ? Tokens[t+1].start : cChars;
644 while( pos < end_pos && text[pos] != '\r' && text[pos] != '\t' ) pos++;
646 if( pos > start_pos )
648 ::TextOut( hMemDC, x * size.cx - offset, y * size.cy,
649 text + start_pos, pos - start_pos );
650 x += pos - start_pos;
653 if( text[pos] == '\r' || pos == cChars )
655 if( sel_start < pos && line_start < sel_end )
658 ::SetBkColor( hMemDC, Scheme.selbk );
659 ::SetTextColor( hMemDC, Scheme.selfk );
660 start = sel_start > line_start ? sel_start : line_start;
661 end = sel_end < pos ? sel_end : pos;
665 int output_count = 0;
666 for( i = line_start; i < start; i++ )
668 xx = text[i] == '\t' ? (xx + TAB_SIZE) & -TAB_SIZE : xx + 1;
671 for( ; i < end; i++ )
673 if( text[i] == '\t' )
675 int cnt = ((xx + output_count + TAB_SIZE) & -TAB_SIZE) -
677 memset( Line + output_count, ' ', cnt );
682 Line[output_count++] = text[i];
685 ::TextOut( hMemDC, xx*size.cx - offset,
686 y*size.cy, Line, output_count );
690 ::TextOut( hMemDC, x*size.cx - offset,
691 y*size.cy, Space, 200 );
693 ::SetBkColor( hMemDC, Scheme.background );
694 ::SetTextColor( hMemDC, Scheme.clr[Tokens[t].type] );
698 if( y >= lines ) break;
703 if( text[pos] == '\t' )
705 x = (x + TAB_SIZE) & -TAB_SIZE;
711 if( pos >= cChars ) break;
713 ::SetTextColor( hMemDC, Scheme.clr[Tokens[t].type]);
718 BitBlt( hScreenDC, 0, 0, rect.right, rect.bottom, hMemDC, 0, 0, SRCCOPY );
719 ::ReleaseDC( hEdit, hScreenDC );
720 ::ShowCaret( hEdit );
726 POINT CHawkView::GetCoord( HWND hEdit, int pos )
731 pt.y = Edit_LineFromChar( hEdit, pos );
732 line_start = Edit_LineIndex( hEdit, pt.y );
733 Edit_GetLine( hEdit, pt.y, Line, LINE_BUF_SIZE );
735 for( i = 0; line_start + i < pos; i++ )
737 pt.x = Line[i] != '\t' ? pt.x + 1 : (pt.x + TAB_SIZE) & -TAB_SIZE;
744 POINT CHawkView::GetCursorPos()
746 DWORD sel = Edit_GetSel( m_hWnd );
747 return GetCoord( m_hWnd, HIWORD( sel ));
751 void CHawkView::GoToLine( int line )
754 int count = Edit_GetLineCount( hEdit );
757 if( --line < 0 ) line = 0;
758 if( line >= count ) line = count - 1;
759 ln_idx = Edit_LineIndex( hEdit, line );
760 Edit_SetSel( hEdit, ln_idx, ln_idx );
762 Edit_ScrollCaret( hEdit );
766 void CHawkView::OnChange()
768 GetDocument()->SetModifiedFlag();
769 RenderHighlightedText(TRUE);
772 HBRUSH CHawkView::CtlColor( CDC* pDC, UINT nCtlColor )
774 pDC->SetTextColor( Scheme.clr[TOKEN_NORMAL]);
775 pDC->SetBkColor( Scheme.background );
776 return Scheme.bkBrush;
779 void CHawkView::OnUntab()
782 DWORD sel = Edit_GetSel(hEdit);
783 int sel_start = LOWORD( sel );
784 int sel_end = HIWORD( sel );
785 if( sel_start != sel_end )
787 int i, line_start, line_end;
790 if( sel_start > sel_end )
797 line_start = Edit_LineFromChar( hEdit, sel_start );
798 line_end = Edit_LineFromChar( hEdit, sel_end );
799 line_end += Edit_LineIndex( hEdit, line_end ) < sel_end;
801 for( i = line_start; i < line_end; i++ )
803 int j, idx = Edit_LineIndex( hEdit, i );
804 Edit_GetLine( hEdit, i, Line, LINE_BUF_SIZE );
805 for( j = 0; j < TAB_SIZE; j++ )
809 j += Line[j] == '\t';
813 Edit_SetSel( hEdit, idx, idx + j );
814 Edit_ReplaceSel( hEdit, "" );
817 Edit_SetSel( hEdit, sel_start, sel_end );
819 RenderHighlightedText( TRUE );
823 void CHawkView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
825 RenderHighlightedText(TRUE);
828 void CHawkView::OnGoHome()
830 Edit_SetSel( m_hWnd, 0, 0 );
831 Edit_ScrollCaret( m_hWnd );
834 void CHawkView::OnGotoLine()
837 m_edit.GetSel(sel1,sel2);
838 CGotoLine dlg(Edit_GetLineCount( m_hWnd ),Edit_LineFromChar(m_hWnd,sel2)+1, this);
840 if(dlg.DoModal() == IDOK)
842 int line = dlg.m_line;
847 void CHawkView::OnTimer(UINT nIDEvent)
851 CEditView::OnTimer(nIDEvent);
854 void CHawkView::UpdateTip()
856 CEdit& edit = GetEditCtrl();
860 return; // Selection is active
863 CString strtext = GetText();
864 const unsigned char* text = (const unsigned char*)LPCTSTR(strtext);
865 int length = GetBufferLength();
868 for(; s1 < length; s1++)
869 if(!((text[s1] >= 'A' && text[s1] <= 'Z') ||
870 (text[s1] >= 'a' && text[s1] <= 'z') ||
871 (text[s1] >= '0' && text[s1] <= '9') ||
875 if(!((text[s2] >= 'A' && text[s2] <= 'Z') ||
876 (text[s2] >= 'a' && text[s2] <= 'z') ||
877 (text[s2] >= '0' && text[s2] <= '9') ||
881 int tokenLength = s1 - s2 - 1;
883 return; // Nothing to update
884 char* token = new char[tokenLength + 1];
885 memcpy(token, &text[s2 + 1], tokenLength);
886 token[tokenLength] = 0;
888 CHawkApp* app = (CHawkApp*)AfxGetApp();
889 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
890 CString tip = app->GenDecl(token);
892 frame->GetStatusBar()->SetPaneText(0, LPCTSTR(tip));