TextLayer_Refresh( LCUI_TextLayer *layer ) /* 标记文本图层中每个字的位图,等待绘制文本图层时进行更新 */ { int i, j; int rows, len; Text_RowData *row_ptr; LCUI_CharData *char_ptr; LCUI_Rect area; rows = Queue_GetTotal( &layer->rows_data ); for(area.y=0,area.x=0,i=0; i<rows; ++i) { row_ptr = Queue_Get( &layer->rows_data, i ); len = Queue_GetTotal( &row_ptr->string ); for(j=0; j<len; ++j) { char_ptr = Queue_Get( &row_ptr->string, j ); if( !char_ptr ) { continue; } char_ptr->need_update = TRUE; } area.height = row_ptr->max_size.h; area.width = row_ptr->max_size.w; RectQueue_Add( &layer->clear_area, area ); area.y += row_ptr->max_size.h; } }
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 TimerList_UpdateTimerPos( LCUI_Queue *timer_list, timer_data *p_timer ) { int n, src_i=-1, des_i=-1; int64_t time_left, tmp_time_left; timer_data *p_tmp_timer; /* 计算该定时器的剩余定时时长 */ time_left = LCUI_GetTicks( p_timer->start_time ); time_left -= p_timer->pause_ms; time_left = p_timer->total_ms - time_left; /* 锁上定时器列表 */ Queue_Lock( &global_timer_list ); n = Queue_GetTotal( &global_timer_list ); while(n--) { p_tmp_timer = (timer_data*)Queue_Get( &global_timer_list, n ); if( !p_tmp_timer ) { continue; } /* 若找到自己的位置,则记录 */ if( p_tmp_timer->id == p_timer->id ) { src_i = n; /* 如果已经找到目标位置,则退出循环 */ if( des_i != -1 ) { break; } continue; } tmp_time_left = LCUI_GetTicks( p_tmp_timer->start_time ); tmp_time_left -= p_tmp_timer->pause_ms; tmp_time_left = p_tmp_timer->total_ms - tmp_time_left; /* 若该定时器的剩余定时时长不大于当前定时器,则记录 */ if( des_i == -1 && time_left >= tmp_time_left ) { DEBUG_MSG("src timer: %d, pos: %d, , cur_ms: %I64dms, des timer: %d, pos: %d, cur_ms: %I64dms\n", p_timer->id, src_i, LCUI_GetTicks(p_timer->start_time), p_tmp_timer->id, des_i, LCUI_GetTicks(p_tmp_timer->start_time) ); des_i = n; /* 如果已经找到源位置,则退出循环 */ if( src_i != -1 ) { break; } } } /* 若目标位置无效,则将末尾作为目标位置 */ if( des_i == -1 ) { DEBUG_MSG("tip\n"); des_i = Queue_GetTotal( &global_timer_list )-1; } /* 若源位置和目标位置有效,则开始移动 */ if( src_i != -1 ) { DEBUG_MSG("src: %d, des: %d\n", src_i, des_i ); Queue_Move( &global_timer_list, des_i, src_i ); } Queue_Unlock( &global_timer_list ); }
TextLayer_Text_GenerateBMP( LCUI_TextLayer *layer ) /* 为文本图层中的文本生成位图,已存在位图的文字将不重新生成 */ { LCUI_BOOL refresh = FALSE; LCUI_Pos pos; int i, j, len, rows; Text_RowData *row_ptr; LCUI_CharData *char_ptr; DEBUG_MSG1("enter\n"); DEBUG_MSG1("thread: %lu\n", thread_self()); rows = Queue_GetTotal( &layer->rows_data ); for( pos.y=0,j=0; j<rows; ++j ) { row_ptr = Queue_Get( &layer->rows_data, j ); len = Queue_GetTotal( &row_ptr->string ); DEBUG_MSG1("row %d, len: %d\n", j, len); for( pos.x=0,i=0; i<len; ++i) { char_ptr = Queue_Get( &row_ptr->string, i ); DEBUG_MSG1("generate FontBMP, get char_ptr: %p, char: %c\n", char_ptr, char_ptr->char_code ); if( !char_ptr || !char_ptr->display ) { DEBUG_MSG1("no display\n"); continue; } if( FontBMP_Valid( char_ptr->bitmap ) ) { DEBUG_MSG1("have FontBMP\n"); if( !refresh ) { pos.x += char_ptr->bitmap->advance.x; continue; } } else { refresh = TRUE; DEBUG_MSG1( "generate FontBMP, char code: %d\n", char_ptr->char_code ); TextLayer_GetCharBMP ( &layer->default_data, char_ptr ); } DEBUG_MSG1( "char_data->bitmap->advance.x: %d\n", char_ptr->bitmap->advance.x ); TextLayer_Clear( layer, pos, row_ptr->max_size.h, char_ptr ); char_ptr->need_update = TRUE; pos.x += char_ptr->bitmap->advance.x; } refresh = FALSE; /* 更新当前行的尺寸 */ TextLayer_Update_RowSize( layer, j ); DEBUG_MSG1("row size: %d,%d\n", row_ptr->max_size.w, row_ptr->max_size.h); pos.y += row_ptr->max_size.h; } DEBUG_MSG1("quit\n"); }
/* 从程序列表中删除一个LCUI程序信息 */ static int LCUIAppList_Delete( LCUI_ID app_id ) { int pos = -1; LCUI_App *app; int i, total; total = Queue_GetTotal(&LCUI_Sys.app_list); /* 如果程序总数大于0,查找程序信息所在队列的位置 */ if (total > 0) { for (i = 0; i < total; ++i) { app = Queue_Get(&LCUI_Sys.app_list, i); if(app->id == app_id) { pos = i; break; } } if(pos < 0) { return -1; } } else { return -1; } /* 从程序显示顺序队列中删除这个程序ID */ Queue_Delete (&LCUI_Sys.app_list, pos); return 0; }
/* 新建一个主循环 */ LCUI_API LCUI_MainLoop* LCUI_MainLoop_New( void ) { LCUI_MainLoop *loop; if( !init_mainloop_queue ) { LCUI_MainLoopQueue_Init(); init_mainloop_queue = TRUE; } loop = LCUI_MainLoop_GetAvailable(); if( loop == NULL ) { loop = (LCUI_MainLoop*)malloc(sizeof(LCUI_MainLoop)); if( !loop ) { return NULL; } } loop->app_id = LCUIApp_GetSelfID(); loop->quit = FALSE; loop->level = Queue_GetTotal( &mainloop_queue ); loop->running = FALSE; Queue_AddPointer( &mainloop_queue, loop ); /* 重新对主循环队列进行排序 */ LCUI_MainLoopQueue_Sort(); return loop; }
/* 从指定线程树的结点中搜索匹配的线程ID,并返回线程树结点的指针 */ static Thread_TreeNode * ThreadTree_Find( Thread_TreeNode *ttn, LCUI_Thread tid ) { int i, n; Thread_TreeNode *new_ttn;\ if(NULL == ttn) { return NULL; } /* 如果是LCUI的一个线程的ID */ if( tid == LCUI_Sys.display_thread || tid == LCUI_Sys.dev_thread || tid == LCUI_Sys.timer_thread ) { tid = thread_tree.tid; } if(ttn != &thread_tree && ttn->tid == tid) { return ttn; } n = Queue_GetTotal( &ttn->child ); for(i=0; i<n; ++i) { new_ttn = Queue_Get( &ttn->child, i ); if( !new_ttn ) { continue; } /* 如果该线程树结点指针有效,就继续递归查找 */ new_ttn = ThreadTree_Find(new_ttn, tid); if( new_ttn ) { return new_ttn; } } return NULL;/* 没有在for循环里返回正常的指针,那么就在这里返回NULL */ }
/* 在线程树中删除一个结点 */ static int ThreadTreeNode_Delete( LCUI_Thread tid ) { int i, n; Thread_TreeNode *tt, *child; tt = ThreadTree_Find(&thread_tree, tid); if(tt == NULL) { return -1; } tt = tt->parent; /* 得到父线程的结点指针 */ if(tt == NULL) { return -2; } n = Queue_GetTotal( &tt->child ); if(n <= 0) { return -3; } for(i=0; i<n; ++i) { child = Queue_Get( &tt->child, i ); if( !child || child->tid != tid ) { continue; } Queue_Delete( &tt->child, i ); return 0; } return -3; }
LCUI_API int WidgetMsg_AddToTask( LCUI_Widget *widget, WidgetMsgData *data_ptr ) { int i,n; LCUI_Queue *msg_func; LCUI_Task *task_ptr, task; /* LCUI系统消息不能作为任务让程序在主循环里处理 */ if( data_ptr->msg_id < WIDGET_USER ) { return -1; } msg_func = Widget_GetMsgFunc( widget ); if( msg_func == NULL ) { return -2; } n = Queue_GetTotal( msg_func ); for(i=0; i<n; ++i) { task_ptr = (LCUI_Task*)Queue_Get( msg_func, i ); if( task_ptr == NULL ) { continue; } if( task_ptr->id != data_ptr->msg_id ) { continue; } task.id = widget->app_id; task.func = task_ptr->func; task.arg[0] = widget; task.arg[1] = data_ptr->data.ptr; task.destroy_arg[0] = FALSE; task.destroy_arg[1] = data_ptr->need_free; AppTasks_Add( &task ); } return 0; }
LCUI_API int WidgetMsg_Connect( LCUI_Widget *widget, uint_t msg_id, WidgetProcFunc func ) { int i,n; LCUI_Queue *msg_func; LCUI_Task *task_ptr, task; msg_func = Widget_GetMsgFunc( widget ); if( msg_func == NULL ) { return -1; } n = Queue_GetTotal( msg_func ); for(i=0; i<n; ++i) { task_ptr = (LCUI_Task*)Queue_Get( msg_func, i ); if( task_ptr == NULL ) { continue; } if( task_ptr->id != msg_id ) { continue; } task_ptr->func = (CallBackFunc)func; return 0; } task.id = msg_id; task.func = (CallBackFunc)func; return Queue_Add( msg_func, &task ); }
/** 处理列表中的设备的数据 */ static void proc_dev_list( void *arg ) { LCUI_Queue *dev_list; dev_func_data *data_ptr; int total, i, timeout_count = 0; dev_list = (LCUI_Queue *)arg; while( LCUI_Active() ) { Queue_Lock( dev_list ); total = Queue_GetTotal( dev_list ); for(i=0; i<total; ++i) { data_ptr = (dev_func_data*)Queue_Get( dev_list, i ); if( !data_ptr || !data_ptr->proc_func ) { continue; } if( data_ptr->proc_func() ) { ++timeout_count; } } Queue_Unlock( dev_list ); if( timeout_count > 20 ) { LCUI_MSleep( 10 ); timeout_count = 0; } LCUI_MSleep( 5 ); } LCUIThread_Exit(NULL); }
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 FramesStream_TimeSub(int time) /* 功能:将各个动画的当前帧的等待时间与指定时间相减 */ { LCUI_Frame *frame; LCUI_Frames *frames; int i, total, pos; Queue_Lock(&frames_stream); total = Queue_GetTotal(&frames_stream); DEBUG_MSG("start\n"); for(i=0; i<total; ++i) { frames = Queue_Get(&frames_stream, i); if( !frames || frames->state == 0 ) { continue; } if(frames->current > 0) { pos = frames->current-1; } else { pos = 0; } frame = Queue_Get(&frames->pic, pos); if( !frame ) { continue; } frame->current_time -= time; DEBUG_MSG("fames: %p, current: %d, time:%ld, sub:%d\n", frames, pos, frame->current_time, time); } DEBUG_MSG("end\n"); Queue_Unlock(&frames_stream); }
LCUI_API int GraphLayer_AddChild( LCUI_GraphLayer *des_ctnr, LCUI_GraphLayer *glayer ) { int i, total; LCUI_GraphLayer *tmp_child; //_DEBUG_MSG( "des_ctnr: %p, glayer: %p\n", des_ctnr, glayer ); /* 容器图层必须有效 */ if( !des_ctnr ) { return -1; } /* 子图层必须有效,并且不能有父图层 */ if( !glayer || glayer->parent ) { //_DEBUG_MSG( "!glayer || glayer->parent\n" ); return -2; } /* 根据队列中的z值,将子图层存放在队列中适当的位置 */ total = Queue_GetTotal( &des_ctnr->child ); for( i=0; i<total; ++i ) { tmp_child = (LCUI_GraphLayer*)Queue_Get( &des_ctnr->child, i ); /* 如果比当前位置的图层的z值小,那就对比下一个位置的图层 */ if( glayer->z_index < tmp_child->z_index ) { continue; } /* 将新图层插入至该位置 */ Queue_InsertPointer( &des_ctnr->child, i, glayer ); break; } /* 如果没找到位置,则直接添加至末尾 */ if( i >= total ) { Queue_AddPointer( &des_ctnr->child, glayer ); } glayer->parent = des_ctnr; return 0; }
LCUI_API int GraphLayer_PrintChildList( LCUI_GraphLayer *glayer ) { int i, n; LCUI_Queue *child_list; LCUI_GraphLayer *child; if( glayer == NULL ) { return -1; } child_list = &glayer->child; if(child_list == NULL) { return -1; } n = Queue_GetTotal( child_list ); _DEBUG_MSG("total glayer: %d\n", n); for(i=0; i<n; ++i) { child = (LCUI_GraphLayer*)Queue_Get( child_list, i ); if( child == NULL ) { continue; } printf("[%d] glayer: %p, z-index: %d, pos: (%d,%d), size: (%d, %d)\n", i, child, child->z_index, child->pos.x, child->pos.y, child->graph.w, child->graph.h ); } return 0; }
LCUI_API int GraphLayer_Sort( LCUI_GraphLayer *glayer ) { LCUI_GraphLayer *child_a, *child_b; int i, j, total; if( !glayer ) { return -1; } /* 排序前先锁上队列互斥锁 */ Queue_Lock( &glayer->child ); total = Queue_GetTotal( &glayer->child ); /* 使用的是冒泡排序法 */ for(j=0; j<total; ++j) for(i=total-1; i>=1; --i) { child_a = (LCUI_GraphLayer*)Queue_Get( &glayer->child, i ); if( !child_a ) { continue; } child_b = (LCUI_GraphLayer*)Queue_Get( &glayer->child, i-1 ); if( !child_b ) { continue; } if( child_a->z_index > child_b->z_index ) { Queue_Move( &glayer->child, i-1, i); } } /* 解开互斥锁 */ Queue_Unlock( &glayer->child ); return 0; }
LCUI_API int GraphLayer_DeleteChild( LCUI_GraphLayer *child_glayer ) { int i, total; LCUI_Queue *child_list; LCUI_GraphLayer *tmp_glayer; if( !child_glayer ) { return -1; } if( !child_glayer->parent ) { return 0; } /* 引用父图层的子图层列表 */ child_list = &child_glayer->parent->child; total = Queue_GetTotal( child_list ); /* 查找子图层记录 */ for( i=0; i<total; ++i ) { tmp_glayer = (LCUI_GraphLayer*)Queue_Get( child_list, i ); /* 若找到则删除该子图层记录 */ if( tmp_glayer == child_glayer ) { Queue_DeletePointer( child_list, i ); child_glayer->parent = NULL; return 0; } } child_glayer->parent = NULL; return 0; }
Frames_Play(LCUI_Frames *frames) /* 功能:播放动画 */ { int i, total; LCUI_Frames *tmp_ptr; if( !frames ) { return -1; } frames->state = 1; if(__timer_id == -1){ Queue_Init( &frames_stream, sizeof(LCUI_Frames), NULL ); Queue_UsingPointer( &frames_stream ); __timer_id = set_timer( 50, Process_Frames, TRUE ); } /* 检查该动画是否已存在 */ Queue_Lock( &frames_stream ); total = Queue_GetTotal( &frames_stream ); for( i=0; i<total; ++i ) { tmp_ptr = Queue_Get( &frames_stream, i ); if( tmp_ptr == frames ) { break; } } Queue_Unlock( &frames_stream ); /* 添加至动画更新队列中 */ if( i>=total ) { return Queue_AddPointer(&frames_stream, frames); } return 1; }
/** * 释放定时器 * 当不需要定时器时,可以使用该函数释放定时器占用的资源 * @param timer_id * 需要释放的定时器的标识符 * @return * 正常返回0,指定ID的定时器不存在则返回-1. * */ LCUI_API int LCUITimer_Free( int timer_id ) { int i, total; timer_data *timer; LCUISleeper_BreakSleep( &timer_sleeper ); Queue_Lock( &global_timer_list ); total = Queue_GetTotal( &global_timer_list ); for(i=0; i<total; ++i) { timer = (timer_data*)Queue_Get( &global_timer_list, i ); if( !timer ) { continue; } if( timer->id == timer_id ) { DEBUG_MSG("delete timer: %d, n_ms: %d\n", timer->id, timer->total_ms); Queue_Delete( &global_timer_list, i ); break; } } Queue_Unlock( &global_timer_list ); if( i < total ) { LCUISleeper_BreakSleep( &timer_sleeper ); return 0; } return -1; }
TextLayer_GetRowLen( LCUI_TextLayer *layer, int row ) /* 获取指定行显式文字数 */ { int total; Text_RowData *row_ptr; total = Queue_GetTotal( &layer->rows_data ); if( row > total ) { row = total; } /* 获取当前行的指针 */ row_ptr = Queue_Get( &layer->rows_data, row ); if( !row_ptr ) { return 0; } return Queue_GetTotal( &row_ptr->string ); }
/** 将指定标签的样式数据从队列中删除,只删除队列尾部第一个匹配的标签 */ static void StyleTag_Delete( LCUI_Queue *tags, StyleTag_ID tag ) { int i, total; StyleTag_Data *p; total = Queue_GetTotal( tags ); DEBUG_MSG("delete start, total tag: %d\n", Queue_GetTotal( tags )); if(total <= 0) { return; } for(i=total-1; i>=0; --i) { p = Queue_Get( tags, i ); if( p->tag == tag ) { Queue_Delete( tags, i ); break; } } DEBUG_MSG("delete end, total tag: %d\n", Queue_GetTotal( tags )); }
/** 获取当前的样式数据 */ LCUI_API LCUI_TextStyle* StyleTag_GetCurrentStyle( LCUI_Queue *tags ) { PX_PT_t pxpt; StyleTag_Data *tag_data; LCUI_TextStyle *style_data; int i, total, equal = 0, flags[MAX_TAG_NUM]; style_data = malloc (sizeof(LCUI_TextStyle)); TextStyle_Init( style_data ); memset( flags, 0, sizeof(flags) ); total = Queue_GetTotal( tags ); if(total <= 0) { free( style_data ); return NULL; } /* 从样式数据队列中获取字体样式数据 */ for(equal=0,i=total-1; i>=0; --i) { tag_data = Queue_Get( tags, i ); DEBUG_MSG("tag id: %d\n", tag_data->tag); switch( tag_data->tag ) { case TAG_ID_COLOR: if( flags[0] != 0 ) { break; } style_data->_fore_color = TRUE; style_data->fore_color = *((LCUI_RGB*)tag_data->style); DEBUG_MSG("color: %d,%d,%d\n", data->fore_color.red, data->fore_color.green, data->fore_color.blue); flags[0] = 1; ++equal; break; case TAG_ID_SIZE: if( flags[1] != 0 ) { break; } pxpt = *((PX_PT_t*)tag_data->style); style_data->_pixel_size = TRUE; style_data->pixel_size = pxpt.px; flags[1] = 1; ++equal; break; default: break; } if(equal == MAX_TAG_NUM) { break; } } if( equal == 0 ) { free( style_data ); return NULL; } return style_data; }
static int __GraphLayer_GetLayers( LCUI_GraphLayer *root_glayer, LCUI_GraphLayer *glayer, LCUI_Rect rect, LCUI_Queue *queue ) { int i, total; LCUI_Pos pos; LCUI_Rect tmp; LCUI_GraphLayer *child; LCUI_Queue *child_list; if( !glayer ) { //_DEBUG_MSG("!glayer\n"); return -1; } if( !glayer->visible ) { //_DEBUG_MSG("!glayer_visible\n"); return 1; } child_list = &glayer->child; /* 从底到顶遍历子部件 */ total = Queue_GetTotal( child_list ); //_DEBUG_MSG( "root: %p, cur: %p, child total: %d\n", // root_glayer, glayer, total ); /* 从尾到首,从底到顶,遍历图层 */ for( i=total-1; i>=0; --i ) { child = (LCUI_GraphLayer*)Queue_Get( child_list, i ); /* 忽略无效或不可见的图层 */ if( !child || !child->visible ) { continue; } /* 获取子图层的有效区域及全局坐标 */ tmp = GraphLayer_GetValidRect( root_glayer, child ); pos = GraphLayer_GetGlobalPos( root_glayer, child ); //_DEBUG_MSG( "child: %p, pos: %d,%d, valid rect: %d,%d, %d, %d\n", // child, pos.x, pos.y, tmp.x, tmp.y, tmp.width, tmp.height); //Graph_PrintInfo( &child->graph ); /* 有效区域加上子部件的全局坐标 */ tmp.x += pos.x; tmp.y += pos.y; /* 判断区域是否有效 */ if( !LCUIRect_IsValid(tmp) ) { continue; } /* 若该有效区域与目标区域重叠,则记录子部件,并进行递归 */ if( LCUIRect_Overlay(tmp, rect) ) { Queue_AddPointer( queue, child ); __GraphLayer_GetLayers( root_glayer, child, rect, queue ); } } return 0; }
static LCUI_BOOL LCUIApp_HaveTask( LCUI_App *app ) { if( !app ) { return FALSE; } if(Queue_GetTotal(&app->tasks) > 0) { return TRUE; } return FALSE; }
/* 更新文本框的样式以及文本图层相关的数据 */ static void TextBox_ExecUpdate( LCUI_Widget *widget ) { LCUI_TextLayer *layer; LCUI_TextBlock *text_ptr; LCUI_TextBox *textbox; textbox = Widget_GetPrivData( widget ); /* 如果缓冲区内有文本块 */ if( Queue_GetTotal( &textbox->text_block_buff ) > 0 ) { /* 获取文本块 */ text_ptr = Queue_Get( &textbox->text_block_buff, 0 ); if( text_ptr ) { //_DEBUG_MSG("text block: %p, text: %p\n", // text_ptr, text_ptr->text); switch( text_ptr->pos_type ) { case AT_TEXT_LAST: /* 将此文本块追加至文本末尾 */ __TextBox_Text_AppendW( widget, text_ptr->text ); break; case AT_CURSOR_POS: /* 将此文本块插入至光标当前处 */ __TextBox_Text_Add( widget, text_ptr->text ); break; default: break; } } /* 删除该文本块 */ Queue_Delete( &textbox->text_block_buff, 0 ); /* 更新滚动条的位置 */ TextBox_ScrollBar_UpdatePos( widget ); /* 标记下次继续更新 */ __Widget_Update( widget ); } /* 如果文本框内没有文本,且还未显示占位符,则设置占位符并显示 */ if( TextBox_Text_GetTotalLength( widget ) == 0 && !textbox->show_placeholder ) { layer = TextBox_GetTextLayer(widget); /* 备份文本框内的文本样式以及屏蔽符 */ textbox->textstyle_bak = layer->default_data; textbox->password_char_bak = layer->password_char.char_code; /* 占位符不能被屏蔽,所以设置屏蔽符为0 */ TextLayer_Text_SetPasswordChar( layer, 0 ); /* 文本框内显示占位符 */ TextLayer_TextW( layer, textbox->placeholder.string ); /* 设置占位符的样式 */ TextLayer_Text_SetDefaultStyle( layer, textbox->placeholder_style ); textbox->show_placeholder = TRUE; } TextBox_ExecUpdateStyle( widget ); /* 更新文本框的样式 */ Widget_ExecUpdate( TextBox_GetLabel( widget ) ); /* 更新文本图层的内容 */ TextBox_ScrollBar_UpdateSize( widget ); /* 更新滚动条的长度 */ TextBox_Cursor_Update( widget ); /* 更新文本框内的光标 */ }
/** 清理部件列表中需要移除的部件,并将部件状态设置为NORMAL */ static void WidgetRecord_Clear( void ) { int i, n; WidgetRecordItem *item; Queue_Lock( &widget_proc_record ); n = Queue_GetTotal( &widget_proc_record ); for(i=0; i<n; ++i) { item = (WidgetRecordItem*) Queue_Get( &widget_proc_record, i ); if( !item->need_delete ) { continue; } Widget_SetState( item->widget, WIDGET_STATE_NORMAL ); Queue_Delete( &widget_proc_record, i ); n = Queue_GetTotal( &widget_proc_record ); --i; } Queue_Unlock( &widget_proc_record ); }
static void TextLayer_Update_RowSize (LCUI_TextLayer *layer, int row ) /* 更新指定行文本位图的尺寸 */ { int total, i; LCUI_Size size; LCUI_CharData *char_data; Text_RowData *row_data; LCUI_TextStyle *style; row_data = Queue_Get( &layer->rows_data, row ); total = Queue_GetTotal( &row_data->string ); style = StyleTag_GetCurrentStyle( &layer->tag_buff ); size = Size(0,14); if( !style ) { if(layer->default_data.pixel_size > 0) { size = Size(0, layer->default_data.pixel_size+2); } } else { if(style->pixel_size > 0) { size = Size(0, style->pixel_size+2); } } free( style ); for( i=0; i<total; ++i ) { /* 如果屏蔽字符有效,则使用该字符的数据 */ if( layer->password_char.char_code > 0 ) { char_data = &layer->password_char; } else { char_data = Queue_Get( &row_data->string, i ); if( !char_data ) { continue; } } size.w += char_data->bitmap->advance.x; if( char_data->data ) { if( char_data->data->_pixel_size ) { if( size.h < char_data->data->pixel_size + 2) { size.h = char_data->data->pixel_size + 2; } } else { if( size.h < 14) { size.h = 14; } } } else { if( size.h < 14) { size.h = 14; } } } row_data->max_size = size; }
/** * 功能:取消指定部件的焦点 * 说明:该部件会得到EVENT_FOCUSOUT事件,并且,会将焦点转移至其它部件 * */ LCUI_API LCUI_BOOL Widget_CancelFocus( LCUI_Widget *widget ) { int i, total, focus_pos; LCUI_Widget *other_widget, **focus_widget; LCUI_Queue *queue_ptr; LCUI_WidgetEvent event; if( !widget || !widget->focus ) { return FALSE; } focus_widget = &RootWidget_GetSelf()->focus_widget; queue_ptr = Widget_GetChildList( widget->parent ); /* 如果该部件并没获得焦点 */ if( *focus_widget != widget ) { return FALSE; } event.type = EVENT_FOCUSOUT; Widget_DispatchEvent( widget, &event ); /* 寻找可获得焦点的其它部件 */ total = Queue_GetTotal( queue_ptr ); focus_pos = WidgetQueue_FindPos( queue_ptr, *focus_widget ); for( i=0; i<focus_pos; ++i ) { other_widget = (LCUI_Widget*)Queue_Get( queue_ptr, i); if( other_widget && other_widget->visible && other_widget->focus ) { event.type = EVENT_FOCUSIN; Widget_DispatchEvent( widget, &event ); *focus_widget = other_widget; break; } } if( i < focus_pos ) { return TRUE; } /* 排在该部件前面的符合条件的部件没找到,就找排在该部件后面的 */ for( i=focus_pos+1; i<total; ++i ) { other_widget = (LCUI_Widget*)Queue_Get( queue_ptr, i); if( other_widget && other_widget->visible && other_widget->focus ) { event.type = EVENT_FOCUSIN; Widget_DispatchEvent( other_widget, &event ); *focus_widget = other_widget; break; } } /* 没找到就复位焦点 */ if( i >= total ) { *focus_widget = NULL; } return TRUE; }
TextLayer_SetRowEnd( LCUI_TextLayer *layer, uint_t row, uint_t start_cols ) /* 为指定行设定结束点,结束点及后面的数据将被删除,但不记录残余文本位图区域 */ { uint_t total, i; Text_RowData *row_data; row_data = Queue_Get( &layer->rows_data, row ); total = Queue_GetTotal( &row_data->string ); /* 移除多余的数据 */ for(i=start_cols; i<total; ++i) { Queue_Delete( &row_data->string, start_cols ); } }
TextLayer_PrintInfo( LCUI_TextLayer *layer ) /* 打印文本图层信息 */ { int32_t i, j, len, rows; Text_RowData *row_ptr; LCUI_CharData *char_ptr; printf( "layer: %p\n", layer ); rows = Queue_GetTotal( &layer->rows_data ); for(j=0; j<rows; ++j) { row_ptr = Queue_Get( &layer->rows_data, j ); len = Queue_GetTotal( &row_ptr->string ); printf( "row[%d/%d], len: %d\n", j, rows, len ); for(i=0; i<len; ++i) { char_ptr = Queue_Get( &row_ptr->string, i ); printf( "char code: %d, display: %d\n", char_ptr->char_code, char_ptr->display ); Print_FontBMP_Info( char_ptr->bitmap ); } } printf("\n\n"); }