static void MoveEol( LPCLASSDATA lpcd ) { /* * Are we already there? */ if ( lpcd->ptCaretPos.x < GETLINE( lpcd )->nLength ) { /* * No, move to the end. */ lpcd->ptCaretPos.x = GETLINE( lpcd )->nLength; /* * Save this position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); } /* * Make sure the care is in the view. */ MakeCaretVisible( lpcd ); /* * Update caret position. */ UpdateCaret( lpcd ); }
void DisplayCaret( LPCLASSDATA lpcd, BOOL bShow ) { /* * Only when we have the focus. */ if ( lpcd->bHasFocus == FALSE ) return; /* * Anything changed? */ if ( bShow != lpcd->bCaretVisible ) { /* * Change it. */ if (( lpcd->bCaretVisible = bShow ) == TRUE ) { int cy = ( Parser->nCaretType == CARET_HORIZONTAL && ! lpcd->bOverwrite ) ? Parser->szCharSize.cy - ( 2 * GetSystemMetrics( SM_CYBORDER )) : 0; SetCaretPos( GetMarginWidth( lpcd ) + GetLineMarginWidth( lpcd ) + (( GetCaretOffset( lpcd, lpcd->ptCaretPos.x ) - lpcd->ptViewPos.x ) * Parser->szCharSize.cx ), ( lpcd->ptCaretPos.y - lpcd->ptViewPos.y ) * Parser->szCharSize.cy + cy ); ShowCaret( lpcd->hWnd ); } else HideCaret( lpcd->hWnd ); } /* * Send caret position message. */ SendCaretMessage( lpcd ); }
static void MoveHome( LPCLASSDATA lpcd ) { /* * Are we already there? */ if ( lpcd->ptCaretPos.x > 0 || lpcd->ptCaretPos.y > 0 ) { /* * No. Put us there. */ lpcd->ptCaretPos.x = lpcd->ptCaretPos.y = 0; /* * Save this position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Make sure the care is in the view. */ MakeCaretVisible( lpcd ); /* * Update caret position. */ UpdateCaret( lpcd ); } }
static void MoveTabBack( LPCLASSDATA lpcd ) { int nScreenPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ), nPos; /* * Are we at the start of the line? */ if ( lpcd->ptCaretPos.x == 0 ) return; /* * Compute the number of characters we are * right of a tab-stop. */ nPos = nScreenPos % Parser->nTabSize; /* * Go left the amount of position computed above * or a whole tab-stop. */ nPos = nScreenPos - ( nPos ? nPos : Parser->nTabSize ); /* * Position the caret. */ lpcd->ptCaretPos.x = GetTextOffset( lpcd, nPos ); /* * Save this position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Make sure the care is in the view. */ MakeCaretVisible( lpcd ); /* * Update caret position. */ UpdateCaret( lpcd ); }
BOOL CaretInView( LPCLASSDATA lpcd ) { int nRealPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Is the current caret position inside * the view area? */ if ( nRealPos >= lpcd->ptViewPos.x && nRealPos <= ( lpcd->ptViewPos.x + ( lpcd->szViewSize.cx - 1 )) && lpcd->ptCaretPos.y >= lpcd->ptViewPos.y && lpcd->ptCaretPos.y <= ( lpcd->ptViewPos.y + ( lpcd->szViewSize.cy - 1 ))) return TRUE; return FALSE; }
static void MoveSol( LPCLASSDATA lpcd ) { int nFirst = 0; LPLINE pLine = GETLINE( lpcd ); /* * Any characters on the line? */ if ( pLine->nLength == 0 ) return; /* * Find first character offset. */ while ( nFirst < pLine->nLength && _istspace( pLine->pcText[ nFirst ] ) ) nFirst++; /* * Are we already there? */ if ( lpcd->ptCaretPos.x > 0 && lpcd->ptCaretPos.x <= nFirst ) /* * No, move to the start. */ lpcd->ptCaretPos.x = 0; else /* * No, move to the start. */ lpcd->ptCaretPos.x = nFirst; /* * Save this position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Make sure the care is in the view. */ MakeCaretVisible( lpcd ); /* * Update caret position. */ UpdateCaret( lpcd ); }
static void MoveLeft( LPCLASSDATA lpcd ) { /* * Caret at the start of the line? */ if ( lpcd->ptCaretPos.x == 0 ) { /* * Yes. Are we at the first line? */ if ( lpcd->ptCaretPos.y > 0 ) { /* * Go up one. */ lpcd->ptCaretPos.y--; /* * Go to the end of the line. */ lpcd->ptCaretPos.x = GETLINE( lpcd )->nLength; } } else /* * One left. */ lpcd->ptCaretPos.x--; /* * Save off this position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Make sure the care is in the view. */ MakeCaretVisible( lpcd ); /* * Update caret position. */ UpdateCaret( lpcd ); }
void UpdateCaret( LPCLASSDATA lpcd ) { /* * Do we have the focus? */ if ( lpcd->bHasFocus == TRUE || lpcd->bDragOver == TRUE ) { /* * Caret inside the view? */ if ( CaretInView( lpcd )) { /* * Already visible? */ if ( lpcd->bCaretVisible == FALSE ) /* * No make it visible. */ DisplayCaret( lpcd, TRUE ); else { /* * Re-position. */ int cy = ( Parser->nCaretType == CARET_HORIZONTAL && ! lpcd->bOverwrite ) ? Parser->szCharSize.cy - ( 2 * GetSystemMetrics( SM_CYBORDER )) : 0; SetCaretPos( GetMarginWidth( lpcd ) + GetLineMarginWidth( lpcd ) + (( GetCaretOffset( lpcd, lpcd->ptCaretPos.x ) - lpcd->ptViewPos.x ) * Parser->szCharSize.cx ), ( lpcd->ptCaretPos.y - lpcd->ptViewPos.y ) * Parser->szCharSize.cy + cy ); } } else if ( lpcd->bCaretVisible == TRUE ) /* * Hide the caret. */ DisplayCaret( lpcd, FALSE ); } /* * Send caret position message. */ SendCaretMessage( lpcd ); }
static void MoveRight( LPCLASSDATA lpcd ) { /* * Caret at the end of the line? */ if ( lpcd->ptCaretPos.x == GETLINE( lpcd )->nLength ) { /* * Yes. Are we at the last line? */ if ( lpcd->ptCaretPos.y < ArrayGetSize( lpcd->lpLines ) - 1 ) { /* * Go down one. */ lpcd->ptCaretPos.y++; lpcd->ptCaretPos.x = 0; } } else /* * One right. */ lpcd->ptCaretPos.x++; /* * Save off this position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Make sure the caret is in the view. */ MakeCaretVisible( lpcd ); /* * Update caret position. */ UpdateCaret( lpcd ); }
static void MoveEnd( LPCLASSDATA lpcd ) { /* * Are we there yet? */ if ( lpcd->ptCaretPos.y == ArrayGetSize( lpcd->lpLines ) - 1 && lpcd->ptCaretPos.x == GETLINE( lpcd )->nLength ) /* * Yes. */ return; /* * Put us on the last line. */ lpcd->ptCaretPos.y = ArrayGetSize( lpcd->lpLines ) - 1; /* * Move us to the end. */ //lpcd->ptCaretPos.x = GETLINE( lpcd )->nLength; // Modified by Stephan (2005-06-08): Don't jump to the end of the line lpcd->ptCaretPos.x = 0; /* * Save this position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Make sure the care is in the view. */ MakeCaretVisible( lpcd ); /* * Update caret position. */ UpdateCaret( lpcd ); }
LRESULT OnReplaceSelection( HWND hWnd, WPARAM wParam, LPARAM lParam, LPCLASSDATA lpcd ) { LPCTSTR lpszText = ( LPCTSTR )lParam; BOOL bDeleted = FALSE; /* * Are we read-only? */ if ( ISREADONLY ) return FALSE; /* * Any text? */ if ( lpszText == NULL || *lpszText == _T( '\0' )) return FALSE; /* * Any marks set? If not return FALSE since we need * to replace a text selection. */ if ( HasMark( lpcd ) == FALSE ) return FALSE; /* * Delete the current selection from the text. */ bDeleted = Delete( lpcd ); /* * Hide the caret. */ DisplayCaret( lpcd, FALSE ); /* * Insert the clipboard contents * into the text. */ InsertText( lpcd, lpcd->ptCaretPos.y, lpcd->ptCaretPos.x, lpszText, &lpcd->ptCaretPos, ! bDeleted ); /* * Update column position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Is the caret inside * the view? */ if ( CaretInView( lpcd ) == FALSE ) /* * No. Move the view to * make it visible. */ MakeCaretVisibleNoRedraw( lpcd ); /* * Re-render. */ InvalidateRect( lpcd->hWnd, NULL, FALSE ); /* * Setup scrollers. */ SetupHScroller( lpcd ); SetupVScroller( lpcd ); /* * We are modified. */ SetModified( lpcd, TRUE ); /* * Show the caret. */ DisplayCaret( lpcd, TRUE ); return TRUE; }
static void MoveNextWord( LPCLASSDATA lpcd ) { /* * Obtain current caret column and a * pointer to the line. */ int nPos = lpcd->ptCaretPos.x; LPLINE lpLine = GETLINE( lpcd ); /* * Are we at the end of the line? */ if ( nPos == lpLine->nLength ) { /* * Yes go down one line and to the * first word on that line. */ if ( lpcd->ptCaretPos.y < ArrayGetSize( lpcd->lpLines ) - 1 ) { /* * Start at 0 */ nPos = 0; /* * Go down. */ lpcd->ptCaretPos.y++; /* * Skip spaces. */ lpLine = GETLINE( lpcd ); if ( lpLine->pcText ) { while ( _istspace( lpLine->pcText[ nPos ] ) && nPos < GETLINE( lpcd )->nLength ) nPos++; } /* * Store new column position. */ lpcd->ptCaretPos.x = nPos; } } else { BOOL bBreakOnNonSpace = FALSE; /* * Are we on a white space? */ if ( _istspace( lpLine->pcText[ nPos ] )) { /* * Skip spaces... */ while ( _istspace( lpLine->pcText[ nPos ] ) && nPos < lpLine->nLength ) nPos++; } else if ( IsDelimiter( lpcd, lpLine->pcText [ nPos ] )) /* A delimiter? */ { /* * Skip all delimiters and white spaces. */ while (( IsDelimiter( lpcd, lpLine->pcText[ nPos ] ) || _istspace( lpLine->pcText[ nPos ] )) && nPos < lpLine->nLength ) { /* * White space? */ if ( _istspace( lpLine->pcText[ nPos ] )) /* * Yes. Break on the next non-white space. */ bBreakOnNonSpace = TRUE; else if ( bBreakOnNonSpace ) /* * Stop at this non-white space. */ break; nPos++; } } else { /* * Skip all non delimiters and white spaces. */ while (( IsDelimiter( lpcd, lpLine->pcText[ nPos ] ) == FALSE || _istspace( lpLine->pcText[ nPos ] )) && nPos < lpLine->nLength ) { /* * White space? */ if ( _istspace( lpLine->pcText[ nPos ] )) /* * Yes. Break on the next non-white space. */ bBreakOnNonSpace = TRUE; else if ( bBreakOnNonSpace ) /* * Stop at this non-white space. */ break; nPos++; } } /* * Store position. */ lpcd->ptCaretPos.x = nPos; } /* * Save this position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Make sure the caret is in the view. */ MakeCaretVisible( lpcd ); /* * Update caret position. */ UpdateCaret( lpcd ); }
/* * Send a caret position message. */ void SendCaretMessage( LPCLASSDATA lpcd ) { NMCARETPOSITION nmcp; HWND hParent; /* * Do we have a parent? */ if (( hParent = GetParent( lpcd->hWnd )) != NULL ) { /* * Fill in the structure. */ nmcp.hdr.code = NMBC_CARETPOSITION; nmcp.hdr.hwndFrom = lpcd->hWnd; nmcp.hdr.idFrom = GetWindowLong( lpcd->hWnd, GWL_ID ); nmcp.ptCaretPos = lpcd->ptCaretPos; /* * Convert to screen coordinates. */ nmcp.ptCaretPos.x = GetCaretOffset( lpcd, nmcp.ptCaretPos.x ); nmcp.ptCaretPos.x++; nmcp.ptCaretPos.y++; /* * Send the notification if the * position really changed. */ if ( nmcp.ptCaretPos.x != lpcd->ptLastPositionSent.x || nmcp.ptCaretPos.y != lpcd->ptLastPositionSent.y ) { SendMessage( hParent, WM_NOTIFY, nmcp.hdr.idFrom, ( LPARAM )&nmcp ); lpcd->ptLastPositionSent = nmcp.ptCaretPos; } } /* * Re-render the line if current line * highlighting is on. */ if ( Parser->bHighlightCurrentLine ) { if ( lpcd->ptCaretPos.y != Parser->nHighlighted ) RenderLine( lpcd, Parser->nHighlighted ); RenderLine( lpcd, lpcd->ptCaretPos.y ); Parser->nHighlighted = lpcd->ptCaretPos.y; } /* * Higlight brackets? */ if ( Parser->bColorBracketMatches ) { /* * Render previous match ( if any ) */ if ( lpcd->ptBracket1.y >= 0 ) RenderLine( lpcd, lpcd->ptBracket1.y ); if ( lpcd->ptBracket2.y != lpcd->ptBracket1.y && lpcd->ptBracket2.y >= 0 ) RenderLine( lpcd, lpcd->ptBracket2.y ); /* * Find match. */ if ( FindMatches( lpcd, &lpcd->ptBracket1, &lpcd->ptBracket2, TRUE ) < 0 ) { /* * No match found. */ lpcd->ptBracket1.x = lpcd->ptBracket1.y = -1; lpcd->ptBracket2.x = lpcd->ptBracket2.y = -1; } /* * Render the lines on which the * matches are found. */ if ( lpcd->ptBracket1.y >= 0 ) RenderLine( lpcd, lpcd->ptBracket1.y ); if ( lpcd->ptBracket2.y != lpcd->ptBracket1.y && lpcd->ptBracket2.y >= 0 ) RenderLine( lpcd, lpcd->ptBracket2.y ); } }
static void MakeVisible( LPCLASSDATA lpcd, BOOL bRedraw ) { int nDiffY = lpcd->ptViewPos.y; BOOL bRender = FALSE; /* * Is the caret visible? */ if ( CaretInView( lpcd ) == FALSE ) { /* * Get "real" caret position. */ int nXPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Is it in the view horizontally? */ if (( nXPos < lpcd->ptViewPos.x ) || ( nXPos > lpcd->ptViewPos.x + ( lpcd->szViewSize.cx - 1 ))) { lpcd->ptViewPos.x = max( 0, nXPos - ( lpcd->szViewSize.cx ) / 2 ); bRender = TRUE; } /* * Is it in the view vertically? */ if ( lpcd->ptCaretPos.y < lpcd->ptViewPos.y ) { lpcd->ptViewPos.y = lpcd->ptCaretPos.y; } else if ( lpcd->ptCaretPos.y > lpcd->ptViewPos.y + ( lpcd->szViewSize.cy - 1 )) { lpcd->ptViewPos.y = max( 0, lpcd->ptCaretPos.y - ( lpcd->szViewSize.cy - 1 )); } /* * Redraw? */ if ( bRedraw ) { /* * Compute difference in Y direction. */ nDiffY = nDiffY - lpcd->ptViewPos.y; /* * View moved? */ if ( nDiffY != 0 && bRender == FALSE ) { /* * Scroll view. */ VScroll( lpcd, nDiffY ); /* * Setup vertical scroller. */ SetupVScroller( lpcd ); } else if ( bRender == TRUE ) { /* * Setup scrollers. */ SetupHScroller( lpcd ); SetupVScroller( lpcd ); /* * Re-render. */ InvalidateRect( lpcd->hWnd, NULL, TRUE ); } } } }
void Paste( LPCLASSDATA lpcd ) { HANDLE hData; LPCTSTR lpszText; BOOL bDeleted = FALSE; /* * Are we read-only? */ if ( ISREADONLY ) return; /* * Valid format on the clipboard? */ if ( IsClipboardFormatAvailable( CF_TEXT ) == FALSE ) return; /* * Any marks set? */ if ( HasMark( lpcd )) bDeleted = Delete( lpcd ); /* * Hide the caret. */ DisplayCaret( lpcd, FALSE ); /* * Open the clipboard. */ if ( OpenClipboard( lpcd->hWnd )) { /* * Get data handle. */ if (( hData = GetClipboardData( CF_TEXT )) != NULL ) { /* * Lock the data. */ if (( lpszText = GlobalLock( hData )) != NULL ) { /* * Insert the clipboard contents * into the text. */ InsertText( lpcd, lpcd->ptCaretPos.y, lpcd->ptCaretPos.x, lpszText, &lpcd->ptCaretPos, ! bDeleted ); /* * Unlock the data handle. */ GlobalUnlock( hData ); } } /* * Close the clipboard. */ CloseClipboard(); } /* * Update column position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Is the caret inside * the view? */ if ( CaretInView( lpcd ) == FALSE ) /* * No. Move the view to * make it visible. */ MakeCaretVisibleNoRedraw( lpcd ); /* * Re-render. */ InvalidateRect( lpcd->hWnd, NULL, FALSE ); /* * Setup scrollers. */ SetupHScroller( lpcd ); SetupVScroller( lpcd ); /* * We are modified. */ SetModified( lpcd, TRUE ); /* * Show the caret. */ DisplayCaret( lpcd, TRUE ); }
BOOL Delete( LPCLASSDATA lpcd ) { /* * Read only? */ if ( ISREADONLY ) return TRUE; /* * Do we have a mark and * is it valid? */ if ( HasMark( lpcd )) { /* * Remove the text. */ DeleteText( lpcd, &lpcd->ptSelStart, &lpcd->ptSelEnd, TRUE ); /* * We _must_ have atleast one * empty line. */ if ( ArrayGetSize( lpcd->lpLines ) == 0 ) { if ( InsertLine( lpcd, NULL, 0, -1, TRUE ) == FALSE ) return FALSE; } /* * Hide the caret. */ DisplayCaret( lpcd, FALSE ); /* * Move to the start position. */ lpcd->ptCaretPos = lpcd->ptSelStart; /* * Update column position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Invalidate marks. */ lpcd->ptSelStart.x = lpcd->ptSelStart.y = -1; lpcd->ptSelEnd.x = lpcd->ptSelEnd.y = -1; /* * Is the caret inside * the view? */ if ( CaretInView( lpcd ) == FALSE ) /* * No. Move the view to * make it visible. */ MakeCaretVisibleNoRedraw( lpcd ); /* * Re-render. */ InvalidateRect( lpcd->hWnd, NULL, FALSE ); /* * Setup scrollers. */ SetupHScroller( lpcd ); SetupVScroller( lpcd ); /* * We are modified. */ SetModified( lpcd, TRUE ); /* * Send status message. */ SendStatusMessage( lpcd ); /* * Show the caret. */ DisplayCaret( lpcd, TRUE ); } return TRUE; }
static void MovePrevWord( LPCLASSDATA lpcd ) { /* * Obtain current caret column and * the line were on. */ int nPos = lpcd->ptCaretPos.x; LPLINE lpLine = GETLINE( lpcd ); /* * Are we at the start of the line? */ if ( nPos == 0 ) { /* * Yes go down one line and to the * end of that line. */ if ( lpcd->ptCaretPos.y > 0 ) { /* * Go up. */ lpcd->ptCaretPos.y--; /* * Put the caret at the end. */ lpcd->ptCaretPos.x = GETLINE( lpcd )->nLength; if ( lpcd->ptCaretPos.x ) /* * Recursivly call ourselves. */ MovePrevWord( lpcd ); } } else { /* * Previous character. */ nPos--; /* * Are we on a white space? */ if ( _istspace( lpLine->pcText[ nPos ] )) { /* * Skip spaces... */ while ( _istspace( lpLine->pcText[ nPos ] ) && nPos ) nPos--; } /* * Start of the line? */ if ( nPos ) { /* * Did we reach a delimiter? */ if ( IsDelimiter( lpcd, lpLine->pcText[ nPos ] )) /* A delimiter? */ { /* * Skip all delimiters. */ while ( IsDelimiter( lpcd, lpLine->pcText[ nPos ] )) { /* * White space? */ if ( _istspace( lpLine->pcText[ nPos ] )) break; /* * Start of the line? */ if ( nPos == 0 ) { /* * Will force the caret at position 0 */ nPos = -1; break; } nPos--; } nPos++; } else { /* * Skip all non delimiters. */ while ( IsDelimiter( lpcd, lpLine->pcText[ nPos ] ) == FALSE ) { /* * White space? */ if ( _istspace( lpLine->pcText[ nPos ] )) break; /* * Start of the line */ if ( nPos == 0 ) { /* * Will force the caret at position 0 */ nPos = -1; break; } nPos--; } nPos++; } } /* * Store position. */ lpcd->ptCaretPos.x = nPos; } /* * Save this position. */ lpcd->nLastColumnPos = GetCaretOffset( lpcd, lpcd->ptCaretPos.x ); /* * Make sure the care is in the view. */ MakeCaretVisible( lpcd ); /* * Update caret position. */ UpdateCaret( lpcd ); }