static LCUI_CharData * TextLayer_GetCurChar( LCUI_TextLayer *layer ) /* 获取光标附近的字符数据的指针 */ { int total; LCUI_Pos pos; LCUI_CharData *char_ptr; Text_RowData *row_ptr; pos = TextLayer_Cursor_GetPos( layer ); row_ptr = Queue_Get( &layer->rows_data, pos.y ); if( !row_ptr ) { return NULL; } char_ptr = Queue_Get( &row_ptr->string, pos.x ); total = Queue_GetTotal( &row_ptr->string ); if( !char_ptr ) { /* 如果当前光标在这行行尾 */ if( pos.x == total ) { char_ptr = row_ptr->last_char; } else { return NULL; } } return char_ptr; }
static void TextBox_TextLayer_Click( LCUI_Widget *widget, LCUI_WidgetEvent *event ) { static LCUI_Pos pos; static LCUI_TextBox *tb; static LCUI_TextLayer *layer; /* 保存当前已获得焦点的部件 */ active_textbox = widget; layer = TextBox_GetTextLayer( widget ); tb = Widget_GetPrivData( active_textbox ); if( tb->show_placeholder ) { pos.x = pos.y = 0; } else { /* 全局坐标转换成相对坐标 */ pos = GlobalPos_ConvTo_RelativePos( tb->text, event->drag.cursor_pos ); } //printf("pos: %d,%d\n", pos.x, pos.y); /* 根据像素坐标,设定文本光标的位置 */ TextLayer_Cursor_SetPixelPos( layer, pos ); /* 获取光标的当前位置 */ pos = TextLayer_Cursor_GetPos( layer ); /* 主要是调用该函数更新当前文本浏览区域,以使光标处于显示区域内 */ TextBox_Cursor_Move( widget, pos ); }
TextLayer_Cursor_GetFixedPixelPos( LCUI_TextLayer *layer ) /* 获取文本图层的光标位置,单位为像素 */ { LCUI_Pos pos; pos = TextLayer_Cursor_GetPos( layer ); pos = TextLayer_Char_GetPixelPos( layer, pos ); return pos; }
TextLayer_Char_GetPixelPos( LCUI_TextLayer *layer, LCUI_Pos char_pos ) /* 获取显示出来的文字相对于文本图层的坐标,单位为像素 */ { LCUI_Pos pixel_pos; Text_RowData *row_ptr; LCUI_CharData *char_ptr; int rows, cols, total; pixel_pos.x = pixel_pos.y = 0; char_pos = TextLayer_Cursor_GetPos( layer ); total = Queue_GetTotal( &layer->rows_data ); if( char_pos.y >= total ) { char_pos.y = total-1; } if( char_pos.y < 0 ) { char_pos.y = 0; } /* 累加pos.y行之前几行的高度 */ for( pixel_pos.y=0,rows=0; rows<char_pos.y; ++rows ) { row_ptr = Queue_Get( &layer->rows_data, rows ); if( !row_ptr ) { continue; } pixel_pos.y += row_ptr->max_size.h; } /* 获取当前行的指针 */ row_ptr = Queue_Get( &layer->rows_data, rows ); if( !row_ptr ) { pixel_pos.y += 2; return pixel_pos; } /* 获取当前行的文字数 */ total = Queue_GetTotal( &row_ptr->string ); if( char_pos.x > total ) { char_pos.x = total; } if( char_pos.x < 0 ) { char_pos.x = 0; } /* 累计宽度 */ for( pixel_pos.x=0,cols=0; cols<char_pos.x; ++cols ) { char_ptr = Queue_Get( &row_ptr->string, cols ); if( !char_ptr ) { continue; } /* 如果设定了屏蔽字符 */ if( layer->password_char.char_code > 0 ) { pixel_pos.x += layer->password_char.bitmap->advance.x; } else { pixel_pos.x += char_ptr->bitmap->advance.x; } } /* 微调位置 */ pixel_pos.y += 2; return pixel_pos; }
/* 在光标处添加文本 */ static void __TextBox_Text_Add( LCUI_Widget *widget, wchar_t *new_text ) { LCUI_Pos cur_pos; LCUI_TextLayer *layer; layer = TextBox_GetTextLayer( widget ); TextLayer_Text_AddW( layer, new_text ); cur_pos = TextLayer_Cursor_GetPos( layer ); TextBox_Cursor_Move( widget, cur_pos ); }
TextBox_Text_Backspace(LCUI_Widget *widget, int n) /* 删除光标左边处n个字符 */ { LCUI_Pos cur_pos; LCUI_TextLayer *layer; layer = TextBox_GetTextLayer( widget ); TextLayer_Text_Backspace( layer, n ); cur_pos = TextLayer_Cursor_GetPos( layer ); TextBox_Cursor_Move( widget, cur_pos ); Widget_Update( widget ); return 0; }
TextLayer_Text_Backspace( LCUI_TextLayer *layer, int n ) /* 删除光标左边处n个字符 */ { int i, row_len; LCUI_Pos char_pos; Text_RowData *row_ptr; if( layer->read_only ) { return -1; } if( n <= 0 ) { return -2; } /* 计算当前光标所在字的位置 */ char_pos = TextLayer_Cursor_GetPos( layer ); DEBUG_MSG2( "before: %d,%d\n", char_pos.x, char_pos.y ); for( i=n; char_pos.y>=0; --char_pos.y ) { row_ptr = Queue_Get( &layer->rows_data, char_pos.y ); row_len = Queue_GetTotal( &row_ptr->string ); if( char_pos.x == -1 ) { char_pos.x = row_len; } for( ; char_pos.x>=0 && i>0; --char_pos.x,--i ); if( i<=0 && char_pos.x >= 0 ) { break; } } DEBUG_MSG2( "after: %d,%d\n", char_pos.x, char_pos.y ); if( i>0 ) { n -= i; } DEBUG_MSG2("start_pos: %d,%d, len: %d\n", char_pos.x, char_pos.y, n); /* 开始删除文字 */ _TextLayer_Text_Delete( layer, char_pos, n ); /* 删除完后,需要将光标向左移动一个位置 */ TextLayer_Cursor_SetPos( layer, char_pos ); return 0; }
static void TextBox_Input( LCUI_Widget *widget, LCUI_WidgetEvent *event ) { static char buff[5]; static int cols, flag, rows; static LCUI_Pos cur_pos; static LCUI_TextLayer *layer; static LCUI_TextBox *textbox; //_DEBUG_MSG("you input: %d\n", event->key.key_code); layer = TextBox_GetTextLayer( widget ); textbox = Widget_GetPrivData( widget ); cur_pos = TextLayer_Cursor_GetPos( layer ); cols = TextLayer_GetRowLen( layer, cur_pos.y ); rows = TextLayer_GetRows( layer ); switch( event->key.key_code ) { case LCUIKEY_HOMEPAGE: //home键移动光标至行首 cur_pos.x = 0; goto mv_cur_pos; case LCUIKEY_END: //end键移动光标至行尾 cur_pos.x = cols; goto mv_cur_pos; case LCUIKEY_LEFT: if( cur_pos.x > 0 ) { cur_pos.x--; } else if( cur_pos.y > 0 ) { cur_pos.y--; cur_pos.x = TextLayer_GetRowLen( layer, cur_pos.y ); } goto mv_cur_pos; case LCUIKEY_RIGHT: if( cur_pos.x < cols ) { cur_pos.x++; } else if( cur_pos.y < rows-1 ) { cur_pos.y++; cur_pos.x = 0; } goto mv_cur_pos; case LCUIKEY_UP: if( cur_pos.y > 0 ) { cur_pos.y--; } goto mv_cur_pos; case LCUIKEY_DOWN: if( cur_pos.y < rows-1 ) { cur_pos.y++; } mv_cur_pos:; /* 移动光标位置 */ if( textbox->show_placeholder ) { cur_pos.x = cur_pos.y = 0; } TextBox_Cursor_Move( widget,cur_pos ); break; case LCUIKEY_BACKSPACE: //删除光标左边的字符 TextBox_Text_Backspace( widget, 1 ); break; case LCUIKEY_DELETE: //删除光标右边的字符 break; default:; if( textbox->limit_mode == 0 ) { flag = 1; } else { flag = 0; } /* 处理文本框的字符输入限制 */ if( Check_Option( textbox->limit_mode, ONLY_0_TO_9 ) ) { if( event->key.key_code >= '0' && event->key.key_code <= '9' ) { ++flag; } } if( Check_Option( textbox->limit_mode, ONLY_a_TO_z ) ) { if( event->key.key_code >= 'a' && event->key.key_code <= 'z' ) { ++flag; } } if( Check_Option( textbox->limit_mode, ONLY_A_TO_Z ) ) { if( event->key.key_code >= 'A' && event->key.key_code <= 'Z' ) { ++flag; } } if( Check_Option( textbox->limit_mode, ONLY_UNDERLINE ) ) { if( event->key.key_code == '_' ) { ++flag; } } //_DEBUG_MSG("input char: %c, %d\n", event->key.key_code, flag); /* 如果该ASCII码代表的字符是可见的 */ if( flag == 1 && (event->key.key_code == 10 || (event->key.key_code > 31 && event->key.key_code < 126)) ) { //wchar_t *text; buff[0] = event->key.key_code; buff[1] = 0; TextBox_Text_Add( widget, buff); //text = TextLayer_Get_Text( layer ); //free( text ); } //向文本框中添加字符 break; } }
TextLayer_Text_Process( LCUI_TextLayer *layer, int pos_type, wchar_t *new_text ) { LCUI_BOOL refresh = TRUE; LCUI_Pos cur_pos, des_pos; int total, cur_len, row, src_pos, total_row, n_ignore = 0; wchar_t *finish, *p, *q; LCUI_Pos tmp_pos; LCUI_CharData *char_ptr, char_data; Text_RowData *cur_row_ptr, *tmp_row_ptr; /* 如果有选中的文本,那就删除 */ //...... DEBUG_MSG1("enter\n"); /* 如果是将文本追加至文本末尾 */ if( pos_type == AT_TEXT_LAST ) { cur_pos.y = Queue_GetTotal( &layer->rows_data ); if( cur_pos.y > 0 ) { --cur_pos.y; } cur_row_ptr = Queue_Get( &layer->rows_data, cur_pos.y ); if( !cur_row_ptr ) { TextLayer_Text_Add_NewRow( layer ); cur_row_ptr = Queue_Get( &layer->rows_data, cur_pos.y ); } cur_pos.x = Queue_GetTotal( &cur_row_ptr->string ); src_pos = Queue_GetTotal( &layer->text_source_data ); des_pos = cur_pos; } else {/* 否则,是将文本插入至光标所在位置 */ cur_pos = TextLayer_Cursor_GetPos( layer ); DEBUG_MSG1( "cur_pos: %d,%d\n", cur_pos.x, cur_pos.y ); cur_row_ptr = Queue_Get( &layer->rows_data, cur_pos.y ); DEBUG_MSG1( "cur_row_ptr: %p\n", cur_row_ptr ); if( !cur_row_ptr ) { TextLayer_Text_Add_NewRow( layer ); cur_row_ptr = Queue_Get( &layer->rows_data, cur_pos.y ); } src_pos = layer->current_src_pos; des_pos = layer->current_des_pos; DEBUG_MSG1( "src_pos: %d\n", src_pos ); DEBUG_MSG1( "des_pos: %d,%d\n", des_pos.x, des_pos.y ); } row = cur_pos.y; total = wcslen( new_text ); total_row = TextLayer_GetRows( layer ); /* 判断当前要添加的字符的总数是否超出最大限制 */ cur_len = Queue_GetTotal( &layer->text_source_data ); if( total + cur_len > layer->max_text_len ) { total = layer->max_text_len - cur_len; } if( total < 0 ) { total = 0; } //_DEBUG_MSG( "layer: %p, cur total: %d, max_len: %d\n", // layer, cur_len, layer->max_text_len ); DEBUG_MSG1( "total char: %d\n", total ); DEBUG_MSG1( "total row: %d\n", total_row ); char_data.bitmap = NULL; /* 先记录这一行需要刷新的区域,起点为光标所在位置 */ TextLayer_CharLater_Refresh( layer, cur_pos ); for(p=new_text, finish=new_text+total; p<finish; ++p) { DEBUG_MSG2( "1, char: %c\n", *p ); if( layer->using_style_tags ) { /* 处理样式的结束标签 */ q = StyleTag_ProcessEndingTag( &layer->tag_buff, p ); if( q ) { /* 计算需忽略的字符数 */ n_ignore = q-p+1; } else { /* 处理样式标签 */ q = StyleTag_ProcessTag( &layer->tag_buff, p ); if( q ) { n_ignore = q-p+1; } } } /* 针对换行符模式为Win(CR/LF)的文本,进行处理 */ if(*p == '\n' || *p == '\r') { /* 计算需要忽略的换行符的数量 */ for( n_ignore=0,q=p; *q == '\n' || *q == '\r'; ++q,++n_ignore); } if(n_ignore > 0) { /* 被忽略的字符的属性都一样,所以只需赋一次值 */ char_data.data = NULL; char_data.display = FALSE; char_data.need_update = FALSE; char_data.bitmap = NULL; } while(n_ignore > 0) { DEBUG_MSG2( "ignore = %d\n", n_ignore ); char_data.char_code = *p++; Queue_Insert( &layer->text_source_data, src_pos, &char_data ); char_ptr = Queue_Get( &layer->text_source_data, src_pos ); /* 如果启用多行显示,并遇到换行符,那就增加新行 */ if( layer->enable_multiline && char_data.char_code == '\n' ) { ++row; if( refresh ) { tmp_pos.x = 0; tmp_pos.y = row; /* 刷新该行后面所有行的字符 */ for( ; tmp_pos.y<total_row; ++tmp_pos.y ) { TextLayer_CharLater_Refresh( layer, tmp_pos ); } refresh = FALSE; } /* 换行符的数据单独保存 */ cur_row_ptr->last_char = char_ptr; /* 在该行插入新行 */ TextLayer_Text_Insert_NewRow( layer, row ); /* 获取新行的行指针 */ tmp_row_ptr = Queue_Get( &layer->rows_data, row ); /* 当前位置后面的字符转移到新行里 */ TextLayer_Text_RowBreak( layer, cur_row_ptr, des_pos.x, tmp_row_ptr ); /* 行指针切换到下一行 */ cur_row_ptr = tmp_row_ptr; /* 更新当前字符坐标 */ des_pos.x = 0; des_pos.y = row; /* 更新总行数 */ total_row = TextLayer_GetRows( layer ); } ++src_pos; --n_ignore; if(n_ignore == 0) { n_ignore = -1; break; } } if(n_ignore == -1) { --p; n_ignore = 0; continue; } DEBUG_MSG2( "2, char: %c\n", *p ); char_data.char_code = *p; char_data.display = TRUE; char_data.need_update = TRUE; char_data.data = StyleTag_GetCurrentStyle( &layer->tag_buff ); /* 插入至源文本中 */ Queue_Insert( &layer->text_source_data, src_pos, &char_data ); /* 获取源文本中的字符数据的指针 */ char_ptr = Queue_Get( &layer->text_source_data, src_pos ); /* 将该指针添加至行数据队列中 */ cur_row_ptr = Queue_Get( &layer->rows_data, des_pos.y ); Queue_InsertPointer( &cur_row_ptr->string, des_pos.x, char_ptr ); ++src_pos; ++des_pos.x; } if( pos_type == AT_CURSOR_POS ) { layer->current_des_pos = des_pos; layer->current_src_pos = src_pos; } DEBUG_MSG1("quit\n"); }