/** 将 widget 与 sruface 进行绑定 */ static void LCUIDisplay_BindSurface( LCUI_Widget widget ) { LCUI_Rect *p_rect; SurfaceRecord *p_sr; if( LCUIDisplay_GetBindSurface(widget) ) { return; } p_sr = NEW( SurfaceRecord, 1 ); p_sr->widget = widget; p_sr->surface = Surface_New(); Surface_SetCaptionW( p_sr->surface, widget->title ); p_rect = &widget->box.graph; if( widget->style->sheet[key_top].is_valid && widget->style->sheet[key_left].is_valid ) { Surface_Move( p_sr->surface, p_rect->x, p_rect->y ); } Surface_Resize( p_sr->surface, p_rect->w, p_rect->h ); if( widget->computed_style.visible ) { Surface_Show( p_sr->surface ); } else { Surface_Hide( p_sr->surface ); } Widget_InvalidateArea( widget, NULL, SV_GRAPH_BOX ); LinkedList_Append( &display.surfaces, p_sr ); }
LCUI_Widget SideBar_AppendItem( LCUI_Widget sidebar, const wchar_t *id, const wchar_t *icon, const wchar_t *text ) { SideBar *sb; SideBarItem *sbi; LCUI_Widget w; int len = id ? wcslen( id ) : 0; wchar_t *new_id = malloc( sizeof( wchar_t )*(len + 1) ); if( !new_id ) { return NULL; } sb = sidebar->private_data; w = LCUIWidget_New( "sidebar-item" ); sbi = w->private_data; id ? wcscpy( new_id, id ) : (new_id[0] = 0, NULL); sbi->id ? free( sbi->id ) : 0; sbi->id = new_id; Widget_Append( sidebar, w ); TextView_SetTextW( sbi->icon, icon ); TextView_SetTextW( sbi->text, text ); Widget_Show( w ); Widget_Show( sbi->icon ); Widget_Show( sbi->text ); LinkedList_Append( &sb->items, sbi ); return w; }
/** 绑定指定ID的事件 */ int $(BindById)( LCUI_EventBox box, int event_id, EventCallBack func, void *func_data, void (*destroy_data)(void*) ) { LCUI_RBTreeNode *node; LCUI_EventSlot *slot; LCUI_EventHandler *handler; void *data; node = RBTree_Search( &box->event_slot, event_id ); if( !node ) { return -1; } slot = (LCUI_EventSlot*)node->data; handler = NEW_ONE(LCUI_EventHandler); DEBUG_MSG("eventbox: %p, handler_id: %d\n", box, box->handler_id); handler->id = ++box->handler_id; handler->func = func; handler->func_data = func_data; handler->destroy_data = destroy_data; LinkedList_Append( &slot->handlers, handler ); /* 将int类型的值转换成void×类型的值 */ data = &slot->id; data = *(void**)data; RBTree_Insert( &box->event_handler, handler->id, data ); return handler->id; }
void LCUIWorker_PostTask( LCUI_Worker worker, LCUI_Task task ) { LCUI_Task newtask; newtask = NEW( LCUI_TaskRec, 1 ); *newtask = *task; LCUIMutex_Lock( &worker->mutex ); LinkedList_Append( &worker->tasks, newtask ); LCUICond_Signal( &worker->cond ); LCUIMutex_Unlock( &worker->mutex ); }
/// //Adds a state to a game object // //Parameters: // GO: Pointer to game object to add state to // state: Pointer to state to add void GObject_AddState(GObject* GO, State* state) { LinkedList_Append(GO->states, state); }
/** 载入CSS代码块,用于实现CSS代码的分块载入 */ static int LCUI_LoadCSSBlock( CSSParserContext ctx, const char *str ) { size_t size = 0; LCUI_Selector s; LinkedListNode *node; ctx->ptr = str; for( ; *ctx->ptr && size < ctx->buffer_size; ++ctx->ptr, ++size ) { switch( ctx->target ) { case TARGET_SELECTOR: switch( *ctx->ptr ) { case '/': goto proc_comment; case '{': ctx->target = TARGET_KEY; ctx->css = StyleSheet(); case ',': ctx->buffer[ctx->pos] = 0; ctx->pos = 0; DEBUG_MSG("selector: %s\n", ctx->buffer); s = Selector( ctx->buffer ); if( !s ) { // 解析出错 ... break; } LinkedList_Append( &ctx->selectors, s ); break; default: ctx->buffer[ctx->pos++] = *ctx->ptr; break; } break; case TARGET_KEY: switch( *ctx->ptr ) { case '/': goto proc_comment; case ' ': case '\n': case '\r': case '\t': case ';': ctx->pos = 0; continue; case ':': break; case '}': ctx->target = TARGET_NONE; goto put_css; default: ctx->buffer[ctx->pos++] = *ctx->ptr; continue; } goto select_parser; case TARGET_VALUE: switch( *ctx->ptr ) { case '/': goto proc_comment; case '}': case ';': goto parse_value; case '\n': case '\r': case '\t': case ' ': if( ctx->pos == 0 ) { continue; } default: ctx->buffer[ctx->pos++] = *ctx->ptr; continue; } break; case TARGET_COMMENT: if( ctx->is_line_comment ) { if( *ctx->ptr == '\n' ) { ctx->target = ctx->target_bak; } break; } if( *ctx->ptr == '/' && *(ctx->ptr - 1) == '*' ) { ctx->target = ctx->target_bak; } break; case TARGET_NONE: default: switch( *ctx->ptr ) { case '/': goto proc_comment; case '\n': case '\t': case '\r': case ' ': case ',': case '{': case '\\': case '"': case '}': continue; default: break; } ctx->pos = 0; ctx->buffer[ctx->pos++] = *ctx->ptr; ctx->target = TARGET_SELECTOR; break; } continue; proc_comment: switch( *(ctx->ptr + 1) ) { case '/': ctx->is_line_comment = TRUE; break; case '*': ctx->is_line_comment = FALSE; break; default: ctx->buffer[ctx->pos++] = *ctx->ptr; continue; } if( ctx->target_bak != TARGET_COMMENT ) { ctx->target_bak = ctx->target; ctx->target = TARGET_COMMENT; } continue; put_css: DEBUG_MSG("put css\n"); /* 将记录的样式表添加至匹配到的选择器中 */ for( LinkedList_Each( node, &ctx->selectors ) ) { LCUI_PutStyleSheet( node->data, ctx->css, ctx->space ); } LinkedList_Clear( &ctx->selectors, (FuncPtr)Selector_Delete ); StyleSheet_Delete( ctx->css ); continue; select_parser: ctx->target = TARGET_VALUE; ctx->buffer[ctx->pos] = 0; ctx->pos = 0; ctx->parser = Dict_FetchValue( self.parsers, ctx->buffer ); DEBUG_MSG("select style: %s, parser: %p\n", ctx->buffer, ctx->parser); continue; parse_value: if( *ctx->ptr == ';' ) { ctx->target = TARGET_KEY; } if( !ctx->parser ) { continue; } ctx->buffer[ctx->pos] = 0; ctx->pos = 0; ctx->parser->parse( ctx->css, ctx->parser->key, ctx->buffer ); DEBUG_MSG("parse style value: %s, result: %d\n", ctx->buffer); if( *ctx->ptr == '}' ) { ctx->target = TARGET_NONE; goto put_css; } } return size; }
/** 对文本进行预处理 */ static int TextLayer_ProcessText( LCUI_TextLayer layer, const wchar_t *wstr, int add_type, LinkedList *tags ) { EOLChar eol; TextRow txtrow; TextCharRec txtchar; LinkedList tmp_tags; LCUI_TextStyle *style = NULL; const wchar_t *p_end, *p, *pp; int cur_col, cur_row, start_row, ins_x, ins_y; LCUI_BOOL is_tmp_tag_stack, need_typeset, rect_has_added; if( !wstr ) { return -1; } need_typeset = FALSE; rect_has_added = FALSE; is_tmp_tag_stack = FALSE; /* 如果是将文本追加至文本末尾 */ if( add_type == TAT_APPEND ) { if( layer->rowlist.length > 0 ) { cur_row = layer->rowlist.length - 1; } else { cur_row = 0; } txtrow = TextLayer_GetRow( layer, cur_row ); if( !txtrow ) { txtrow = TextRowList_AddNewRow( &layer->rowlist ); } cur_col = txtrow->length; } else { /* 否则,是将文本插入至当前插入点 */ cur_row = layer->insert_y; cur_col = layer->insert_x; txtrow = TextLayer_GetRow( layer, cur_row ); if( !txtrow ) { txtrow = TextRowList_AddNewRow( &layer->rowlist ); } } start_row = cur_row; ins_x = cur_col; ins_y = cur_row; /* 如果没有可用的标签栈,则使用临时的标签栈 */ if( !tags ) { is_tmp_tag_stack = TRUE; StyleTags_Init( &tmp_tags ); tags = &tmp_tags; } p_end = wstr + wcslen( wstr ); for( p = wstr; p < p_end; ++p ) { /* 如果启用的样式标签支持,则处理样式的结束标签 */ if( layer->is_using_style_tags ) { pp = StyleTags_ScanEndingTag( tags, p ); if( pp ) { /* 抵消本次循环后的++p,以在下次循环时还能够在当前位置 */ p = pp - 1; style = StyleTags_GetTextStyle( tags ); LinkedList_Append( &layer->style_cache, style ); continue; } pp = StyleTags_ScanBeginTag( tags, p ); if( pp ) { p = pp - 1; style = StyleTags_GetTextStyle( tags ); LinkedList_Append( &layer->style_cache, style ); continue; } } if( *p == '\r' || *p == '\n' ) { /* 判断是哪一种换行模式 */ if( *p == '\r' ) { if( p + 1 < p_end && *(p + 1) == '\n' ) { eol = EOL_CR_LF; } else { eol = EOL_CR; } } else { eol = EOL_LF; } /* 如果没有记录过文本行的矩形区域 */ if( !rect_has_added ) { TextLayer_InvalidateRowsRect( layer, ins_y, -1 ); rect_has_added = TRUE; start_row = ins_y; } /* 将当前行中的插入点为截点,进行断行 */ TextLayer_BreakTextRow( layer, ins_y, ins_x, eol ); layer->width = max( layer->width, txtrow->width ); need_typeset = TRUE; ++layer->length; ins_x = 0; ++ins_y; txtrow = TextLayer_GetRow( layer, ins_y ); continue; } txtchar.style = style; txtchar.char_code = *p; TextChar_UpdateBitmap( &txtchar, &layer->text_style ); TextRow_InsertCopy( txtrow, ins_x, &txtchar ); ++layer->length; ++ins_x; } /* 更新当前行的尺寸 */ TextLayer_UpdateRowSize( layer, txtrow ); layer->width = max( layer->width, txtrow->width ); if( add_type == TAT_INSERT ) { layer->insert_x = ins_x; layer->insert_y = ins_y; } /* 若启用了自动换行模式,则标记需要重新对文本进行排版 */ if( layer->is_autowrap_mode || need_typeset ) { TextLayer_AddUpdateTypeset( layer, cur_row ); } else { TextLayer_InvalidateRowRect( layer, cur_row, 0, -1 ); } /* 如果已经记录过文本行矩形区域 */ if( rect_has_added ) { TextLayer_InvalidateRowsRect( layer, start_row, -1 ); rect_has_added = TRUE; } /* 如果使用的是临时标签栈,则销毁它 */ if( is_tmp_tag_stack ) { StyleTags_Clear( tags ); } return 0; }