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

📄 atbeditor.c

📁 GSM手机设计软件代码
💻 C
📖 第 1 页 / 共 5 页
字号:
}


/*******************************************************************************

 $Function:		ATB_edit_GetCasePref 

 $Description:	Returns the preferred case for the current position in the editor

 $Returns:		ED_CASEPREF_NUM					- Any numeric character
 				ED_CASEPREF_ALPHA_UC			- Any symbolic or alphabetic uppercase
 											  character
 				ED_CASEPREF_ALPHA_LC			- Any symbolic or alphabetic lowercase
 											  character
   				ED_CASEPREF_ALPHANUM			- Any symbolic, numeric, or alphabetic
 											  character
 				ED_CASEPREF_ALPHANUM_UC			- Any symbolic, numeric, or alphabetic
 											  uppercase character
				ED_CASEPREF_ALPHANUM_LC			- Any symbolic, numeric, or alphabetic
 											  lowercase character

 $Arguments:	editor		- The editor data
 
*******************************************************************************/

T_ED_CASE_PREF ATB_edit_GetCasePref(T_ED_DATA *editor)
{
	T_ED_CASE_PREF	casePref;
	char			formatchar;
	char			*format;

	/* FORMATTED MODE */
	
	if (ATB_edit_Mode(editor, ED_MODE_FORMATTED))
	{
		format = editor->attr->FormatString;
		formatchar = format[editor->formatIndex];
	  
		if ((formatchar>'0' && formatchar<='9') || formatchar=='*')			// Delimiter for format field
		{
	       	editor->formatIndex++;
	       	editor->fieldIndex = 0;
	       	formatchar = format[editor->formatIndex];						// Next character is the format for the field
		}

	    switch(formatchar)
		{
			case 'X':														/* Uppercase alphanumeric */
				casePref = ED_CASEPREF_ALPHANUM_UC;
				break;
			case 'x':
				casePref = ED_CASEPREF_ALPHANUM_LC;								/* Lowercase alphanumeric */
				break;
			case 'A':														/* Uppercase alphabetic */
				casePref = ED_CASEPREF_ALPHA_UC;
				break;
			case 'a':														/* Lowercase alphabetic */
				casePref = ED_CASEPREF_ALPHA_LC;
				break;
			case 'M':
				casePref = ED_CASEPREF_ALPHANUM;
				break;
			case 'm':
				casePref = ED_CASEPREF_ALPHANUM;
				break;
			case 'N':
				casePref = ED_CASEPREF_NUM;
				break;
				
			default:
				casePref = ED_CASEPREF_NONE;
				break;
	    }
	}

	/* NORMAL MODE */
	else
	{
		if (ATB_edit_Mode(editor, ED_MODE_ALPHA))
			casePref = ED_CASEPREF_ALPHANUM;
		else
			casePref = ED_CASEPREF_NUM;
	}
	
	return casePref;
}


/*******************************************************************************

 $Function:		ATB_edit_OutTextLines

 $Description:	Draw the visible lines of text onto the screen
 
 $Returns:		None

 $Arguments:	editor		- The editor data

*******************************************************************************/

static void ATB_edit_OutTextLines (T_ED_DATA *editor)
{
	USHORT		editX			= editor->attr->win_size.px;				/* X position in editor */
	USHORT		editY			= editor->attr->win_size.py;				/* Y position in editor */
	USHORT		editWidth		= editor->attr->win_size.sx;				/* Height of the editor */
	USHORT		editHeight		= editor->attr->win_size.sy;				/* Height of the editor */
	USHORT		lineNo;
	USHORT		heightOnScreen;										/* Height of lines shown so far */
	USHORT		offsetX;											/* X offset of line */
	T_DS_TEXTFORMAT	tempFormat;										/* Temporary storage for format attributes */
	T_ED_LINE	*line;												/* Current line attributes */
	T_ATB_TEXT	currentLine;										/* Current line */
	
	TRACE_FUNCTION("ATB_edit_OutTextLines()");

	if (editor == NULL)
		return;

	heightOnScreen = 0;
	line = ATB_edit_LineGet(editor, editor->winStartLine);
	
	for (lineNo = editor->winStartLine; lineNo < editor->numLines && heightOnScreen<=editHeight; lineNo++)
	{
    	heightOnScreen 	+= line->height;							/* Add this height to the total height so far... */

		if (editor->display && heightOnScreen <= editHeight)		/* and make sure this fits onto the screen */
		{
			currentLine.len = line->next->pos - line->pos;  		/* End of line is the first character of the next line */
			currentLine.dcs = editor->attr->text.dcs;
			currentLine.data = &editor->attr->text.data[line->pos*ATB_string_Size(&currentLine)];

			offsetX = 0;
			if (line->format.attr & DS_ALIGN_RIGHT)
			{
				offsetX = editWidth-ATB_display_StringWidth(&currentLine, &line->format);
			}
			else if (line->format.attr & DS_ALIGN_CENTRE)
			{
				offsetX = (editWidth-ATB_display_StringWidth(&currentLine, &line->format))/2;
			}
			ATB_display_CopyFormat(&tempFormat, &line->format);		/* So format of lines doesn't change */
			ATB_display_Text(offsetX+editX, editY, &tempFormat, &currentLine);
		}

		editY += line->height;										/* Move down by line height, ready for the next one */
		line = line->next;											/* Get next line */
	}

    return;
}


/*******************************************************************************

 $Function:		ATB_edit_Update

 $Description:	Update editor (without displaying), moving cursor up or down by 'dy' lines.

  This function goes through the text, word-wraps it with the help of ATB_edit_WordWrap,
  and works out the start position of text on-screen and the X and Y pixel positions
  of the cursor (with the help of ATB_edit_UpdateCursorPos).  The character position of
  the start of each line within the string is stored, so that ATB_edit_OutTextLines can
  quickly display the editor contents without further calculation.
 
 $Returns:		ED_BAD_HANDLE	- Editor data pointer is null
 				ED_OK			- OK

 $Arguments:	editor		- The editor data
 				dy			- number of lines (+ or -) that the cursor must scroll
 								up or down.

*******************************************************************************/

static ED_RES ATB_edit_Update (T_ED_DATA *editor, int dy)
{
	USHORT				cursorCharPos;			/* New cursor character position */
	USHORT				linePos;				/* Char pos in string of current line. */
	USHORT				lineNo;					/* Line being considered */
	USHORT				editComplete;			/* Flag indicating cursor position found/updated or end of line reached. */
	USHORT				character;				/* Current unicode char. */
	T_ED_LINE			*line;					/* Pointer to current entry in line chain */
	USHORT				cursorColumn;			/* Column cursor is in - always multiple of 8 pixels */
	
	TRACE_FUNCTION("ATB_edit_Update()");

	/* Make sure the editor exists and has text in it */
	
	if (!editor)
		return ED_BAD_HANDLE;

	/* For non read-only modes, or on first process, perform word wrap */

	if (!ATB_edit_Mode(editor, ED_MODE_READONLY) || editor->initialised==FALSE)
	{
		editor->viewStartPos = 0;
		editor->viewHeight = 0;
		editor->totalHeight = 0;
		editor->startOfLine = TRUE;								/* We're at the start of a line */	
		editor->endOfText = FALSE;
		editor->precedingEOL = FALSE;							/* Used to detect if preceding character was CR/LF */
		editor->thischar.lineWidth = 0;							/* Width of current line */
		editor->cursor.line = 0;								/* Line that the cursor is on */
		editor->space.pos = 0;									/* Possible position for soft linebreak - none as yet */

		/* Set up data if this is the first time... */
		
		if (!editor->initialised)
		{
			editor->thischar.pos = 0;
			editor->numLines = 0;								/* total number of lines in editor, start at 0 */

			line = ATB_edit_LineGet(editor, 0);
			line->pos = 0;										/* first line starts at start of buffer */
			line->height = 0;									/* Height of first line */
			ATB_display_CopyFormat(&line->format, &editor->attr->startFormat);	/* Start with this text formatting */
			ATB_display_CopyFormat(&editor->thischar.format, &editor->attr->startFormat); // Start with this text formatting
			
			editor->winStartLine = 0;							/* First line to be displayed in window */

			editor->initialised = TRUE;
		}
		
		/* Set up data if this is NOT the first time */

		else
		{
			/* We only need to word wrap text that might have been changed by user text entry.
			 * The user can affect the previous line (by inserting a space or deleting, so the word is
			 * wrapped to a previous line) and all subsequent lines.  Therefore if we start word wrapping
			 * on the line previous to where the cursor is, we can encompass all changes. */
			line = ATB_edit_LineGet(editor, 0);
			for (lineNo = 0; lineNo<editor->numLines && editor->cursor.pos>=line->pos; lineNo++)
			{
				line = line->next;
			}
			if (lineNo>0)
				lineNo--;
			if (lineNo>0)
				lineNo--;

			line = ATB_edit_LineGet(editor, lineNo);
			editor->thischar.pos = line->pos;							/* Start looking at this line */						
			editor->numLines = lineNo;									/* This no. of lines so far */								
			ATB_display_CopyFormat(&editor->thischar.format, &line->format); /* Start with this text formatting */
			line->height = 0;											/* Height of first line */
		}


		/* Set up some values */
		
		cursorCharPos	= editor->cursor.pos;						/* Cursor position in the string */
		linePos			= 0;										// Position on the current line
			
		/* Word wrap the text into separate lines, storing the start position and height of each.
		 * Also, find the cursor and work out its X position. */
		
		while(!editor->endOfText)									// Go through from first character to last character
		{
			ATB_edit_WordWrap(editor);      						// What is the character?  What's its width?

			if (editor->endOfLine)									// Newline, or current char will not fit on previous line.
			{
				editor->numLines++;								// We've got another line
				editor->startOfLine = TRUE;						// New line is starting
			}
							
			if (editor->startOfLine)
			{
				line = ATB_edit_LineGet(editor, editor->numLines);
				line->pos = editor->startPos;
				line->height = editor->thischar.height; // Height of line set to that of first character
				ATB_display_CopyFormat(&line->format,&editor->thischar.format);
																	/* Formatting at start of line to that of 1st character */
				editor->thischar.lineWidth = 0;

				line = ATB_edit_LineGet(editor, editor->winStartLine);
				if (editor->startPos <= line->pos)	/* Is this the first line to be displayed in the editor? */
				{
					editor->winStartLine = editor->numLines;					/* If so, set this line to the start window line */
				}
				editor->startOfLine = FALSE;
			}

			if (editor->endOfText)												/* If it's a unicode terminator... */
			{
				if (cursorCharPos > editor->thischar.pos)						/* Cursor is past end of text - move to char before end of line. */
					cursorCharPos = editor->thischar.pos;
			}

			if (editor->startPos == cursorCharPos)					// We've found the cursor
			{
				editor->cursor.line 	= editor->numLines;				// Store the line it's on
				editor->cursor.width	= editor->thischar.width;			// Set the width of the cursor
				editor->cursor.x		= editor->thischar.lineWidth;			// And its position
				editor->cursor.attr		= editor->thischar.format.attr;			// Save the format attribute
			}

			editor->thischar.lineWidth += editor->thischar.width;
			editor->thischar.pos++;
		}					// End while

		editor->numLines++;										// Number of lines is one more than the last line
		line = ATB_edit_LineGet(editor, editor->numLines);
		line->pos = editor->thischar.pos;		// End of last line
		
		ATB_edit_UpdateCursorPos(editor);								// Update, but if dy!=0 we may have to change this
	}
	
	/* We now have the start position of each line and its height stored in an array.
	 * We also have the cursor's current X position on its line (but its line may be offscreen) */

	if (dy)														// If we're sending the cursor up/down some lines...
	{
		editor->cursor.line = editor->cursor.line+dy;	// Change cursor line
	
		if (editor->cursor.line >= editor->numLines )		// Make sure line cursor is on doesn't go beyond...
			editor->cursor.line = editor->numLines-1;		// ...last line of editor...

		if (editor->cursor.line < 0)					// ...or above...
			editor->cursor.line = 0;							// ...first line of editor

		/* In read-only mode, stop scrolling down when the bottom line of the text
		 * is visible at the bottom of the window */
		 
		if (ATB_edit_Mode(editor,ED_MODE_READONLY))
		{
			if (editor->numLines>=editor->linesPerScreen
				&& editor->cursor.line >= (editor->numLines - editor->linesPerScreen))
			{
				editor->cursor.line = (editor->numLines - editor->linesPerScreen);
			}
			
			editor->winStartLine = editor->cursor.line;
		}	
	}

	/* Reset all our horizontal variables */
	
	editor->thischar.pos		= 0;
	editor->thischar.lineWidth	= 0;
	editComplete				= TRUE;
	editor->endOfText			= FALSE;
	editor->space.pos			= 0;

	/* Work out how many lines fit on the current screen */

	ATB_edit_UpdateCursorPos(editor); 
	lineNo = 0;

	/* Update the line where we start showing the text on the window */
	
	if (editor->cursor.line < editor->winStartLine) 	//cursor is on a line before current window screen
	{
		editor->winStartLine = editor->cursor.line;
		editComplete = FALSE;
	}
	else if (editor->cursor.line >= (editor->winStartLine+editor->linesPerScreen)) //cursor is below the bottom of the screen
	{
		editor->winStartLine = editor->cursor.line-(editor->linesPerScreen-1);
		editComplete = FALSE;
	}
	
	if (dy!= 0)														/* If we're moving up or down */
	{
		editComplete = FALSE;
	}

	if (!editComplete)												/* Calculate new cursor X and Y positions */
	{
		if (dy!=0)													/* If we've changed line, find new X position */
		{
			line = ATB_edit_LineGet(editor, editor->cursor.line);
			editor->thischar.lineWidth = 0;
			linePos = line->pos;		// Start of current line
			ATB_display_CopyFormat(&editor->thischar.format, &line->format); // Format attributes of 1st character
			/* Get column - is always a multiple of the maximum character width.  Makes sure cursor doesn't wander
			 * left or right too much when moving up or down by lines */
			cursorColumn = editor->cursor.x - (editor->cursor.x % ATB_display_GetMaxCharWidth(&editor->thischar.format));

			/* Search until we're in the column or at the end of the line */
			while (editor->thischar.lineWidth<cursorColumn && linePos < (line->next->pos-1))
			{
				character = ATB_string_GetChar(&editor->attr->text, linePos);
				editor->thischar.width = ATB_display_GetCharWidth(character, &editor->thischar.format);		// Character width
				editor->thischar.lineWidth += editor->thischar.width;
				linePos++;
			}
			/* Set the new cursor X position */
			cursorCharPos			= linePos;									// New cursor position in buffer
			editor->cursor.width	= editor->thischar.width;					// Set the width of the cursor
			editor->cursor.x		= editor->thischar.lineWidth;				// And its position
			editor->cursor.attr		= editor->thischar.format.attr;				// Save the format attribute
		}
		ATB_edit_UpdateCursorPos(editor);
	}

	/* Change cursor position */
	
	editor->cursor.pos = cursorCharPos;

    return ED_OK;
}


/*******************************************************************************

 $Function:		ATB_edit_WordWrap

 $Description:	Main word wrap function.  Takes in the characters of the string
				one by one, calculating the total width displayed on screen and setting flags
				when a string should be wrapped, a carriage return is encountered, the end
				of string has been reached.
				
				Tracks the last space character and goes back there when a word runs over
				the edge of the screen.  Also works out the height of the current line, based on
				the maximum character height found.
 
 $Returns:		None

 $Arguments:	editor		- The editor data

*******************************************************************************/

static void ATB_edit_WordWrap(T_ED_DATA *editor)
{
	USHORT		character;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -