Ejemplo n.º 1
0
/** 追加子部件 */
int $(Append)( LCUI_Widget container, LCUI_Widget widget )
{
	int i, n;
	LCUI_Widget old_container;
	LCUI_WidgetEvent e;
	DEBUG_MSG("container: %p, widget: %p\n", container, widget);
	if( !container || !widget || container == widget->parent ) {
		return -1;
	}
	if( container == widget ) {
		return -2;
	}
	if( widget->parent ) {
		old_container = widget->parent;
	} else {
		goto remove_done;
	}

	/* 移除在之前的容器中的记录 */
	n = LinkedList_GetTotal( &old_container->children );
	for( i=0; i<n; ++i ) {
		LinkedList_Goto( &old_container->children, i );
		if( LinkedList_Get(&old_container->children) == widget ) {
			LinkedList_Delete( &old_container->children );
			break;
		}
	}
	/* 如果是从根级部件中移出,则触发 WET_REMOVE 事件 */
	if( i < n && old_container == LCUIRootWidget ) {
		e.type_name = "TopLevelWidget";
		e.target = widget;
		Widget_PostEvent( LCUIRootWidget, &e, (int*)WET_REMOVE );
	}
	n = LinkedList_GetTotal( &old_container->children_show );
	for( i=0; i<n; ++i ) {
		LinkedList_Goto( &old_container->children_show, i );
		if( LinkedList_Get(&old_container->children_show) == widget ) {
			LinkedList_Delete( &old_container->children_show );
			break;
		}
	}

remove_done:

	widget->parent = container;
	LinkedList_AddData( &container->children, widget );
	LinkedList_AddData( &container->children_show, widget );
	/* 如果是添加至根部件内,则触发 WET_ADD 事件 */
	if( container == LCUIRootWidget ) {
		int ret;
		e.type_name = "TopLevelWidget";
		e.target = widget;
		ret = Widget_PostEvent( LCUIRootWidget, &e, (int*)WET_ADD );
		DEBUG_MSG("post done, ret = %d\n", ret);
	}
	Widget_UpdateTaskStatus( widget );
	DEBUG_MSG("tip\n");
	return 0;
}
Ejemplo n.º 2
0
Archivo: event.c Proyecto: aem3372/LCUI
/** 解除事件连接 */
int $(Unbind)( LCUI_EventBox box, int handler_id )
{
	int i, n;
	LCUI_RBTreeNode *node;
	LCUI_EventSlot *slot;
	LCUI_EventHandler *handler;

	if( !(node = RBTree_Search(&box->event_handler, handler_id)) ) {
		return -1;
	}
	if( !(node = RBTree_Search(&box->event_slot, (int)(node->data))) ) {
		return -2;
	}
	slot = (LCUI_EventSlot*)node->data;
	LinkedList_Goto( &slot->handlers, 0 );
	n = LinkedList_GetTotal( &slot->handlers );
	for( i=0; i<n; ++i ) {
		handler = (LCUI_EventHandler*)LinkedList_Get( &slot->handlers );
		if( handler->id == handler_id ) {
			LinkedList_Delete( &slot->handlers );
			RBTree_Erase( &box->event_handler, handler_id );
			return 0;
		}
		LinkedList_ToNext( &slot->handlers );
	}
	return -3;
}
Ejemplo n.º 3
0
static int LCUI_RunTask(void)
{
	LCUI_Task *task, task_bak;
	LCUIMutex_Lock( &MainApp.task_run_mutex );
	LCUIMutex_Lock( &MainApp.task_list_mutex );
	task = (LCUI_Task*)LinkedList_Get( &MainApp.task_list );
	if( !task ) {
		LCUIMutex_Unlock( &MainApp.task_list_mutex );
		LCUIMutex_Unlock( &MainApp.task_run_mutex );
		return -1;
	}
	if( !task->func ) {
		LinkedList_Delete( &MainApp.task_list );
		LCUIMutex_Unlock( &MainApp.task_list_mutex );
		LCUIMutex_Unlock( &MainApp.task_run_mutex );
		return -2;
	}
	/* 备份该任务数据 */
	task_bak = *task;
	/* 重置数据 */
	task->func = NULL;
	task->arg[0] = NULL;
	task->arg[1] = NULL;
	task->destroy_arg[0] = FALSE;
	task->destroy_arg[1] = FALSE;
	/* 删除之 */
	LinkedList_Delete( &MainApp.task_list );
	/* 解锁,现在的任务数据已经与任务列表独立开了 */
	LCUIMutex_Unlock( &MainApp.task_list_mutex );
	/* 调用函数指针指向的函数,并传递参数 */
	task_bak.func( task_bak.arg[0], task_bak.arg[1] );
	/* 若需要在调用回调函数后销毁参数 */
	if( task_bak.destroy_arg[0] && task_bak.arg[0] ) {
		if( task_bak.destroy_func[0] ) {
			task_bak.destroy_func[0]( task_bak.arg[0] );
		}
		free( task_bak.arg[0] );
	}
	if( task_bak.destroy_arg[1] && task_bak.arg[1] ) {
		if( task_bak.destroy_func[1] ) {
			task_bak.destroy_func[1]( task_bak.arg[1] );
		}
		free( task_bak.arg[1] );
	}
	LCUIMutex_Unlock( &MainApp.task_run_mutex );
	return 0;
}
Ejemplo n.º 4
0
Archivo: event.c Proyecto: aem3372/LCUI
/** 从已触发的事件记录中删除一个事件信息 */
int $(DeleteEvent)( LCUI_EventBox box )
{
	LinkedList *elist;
	elist = &box->events[box->current == 1 ? 0:1];
	if( LinkedList_GetTotal( elist ) <= 0 ) {
		return -2;
	}
	LinkedList_Delete( elist );
	return 0;
}
Ejemplo n.º 5
0
static void LCUIDisplay_CleanSurfaces( void )
{
	int i, n;
	SurfaceRecord *p_sr;

	n = LinkedList_GetTotal( &display.surfaces );
	for( i=0; i<n; ++i ) {
		LinkedList_Goto( &display.surfaces, 0 );
		p_sr = (SurfaceRecord*)
		LinkedList_Get( &display.surfaces );
		Surface_Delete( p_sr->surface );
		LinkedList_Delete( &display.surfaces );
	}
}
Ejemplo n.º 6
0
/** 解除 widget 与 sruface 的绑定 */
static void LCUIDisplay_UnbindSurface( LCUI_Widget widget )
{
	int i, n;
	SurfaceRecord *p_sr;

	n = LinkedList_GetTotal( &display.surfaces );
	for( i=0; i<n; ++i ) {
		LinkedList_Goto( &display.surfaces, i );
		p_sr = (SurfaceRecord*)
		LinkedList_Get( &display.surfaces );
		if( p_sr->widget != widget ) {
			continue;
		}
		Surface_Delete( p_sr->surface  );
		LinkedList_Delete( &display.surfaces );
		break;
	}
}
Ejemplo n.º 7
0
/** 更新各种图形元素的显示 */
static void LCUIDisplay_Update(void)
{
	int i, n, j, m;
	LCUI_Rect *p_rect;
	SurfaceRecord *p_sr;
	LCUI_DirtyRectList rlist;
	LCUI_PaintContext paint;

	DirtyRectList_Init( &rlist );
	n = LinkedList_GetTotal( &display.surfaces );
	/* 遍历当前的 surface 记录列表 */
	for( i=0; i<n; ++i ) {
		LinkedList_Goto( &display.surfaces, i );
		p_sr = (SurfaceRecord*)
		LinkedList_Get( &display.surfaces );
		if( !p_sr->widget || !p_sr->surface
		 || !Surface_IsReady(p_sr->surface) ) {
			continue;
		}
		/* 更新表面 */
		Surface_Update( p_sr->surface );
		/* 收集无效区域记录 */
		Widget_ProcInvalidArea( p_sr->widget, &rlist );
		m = LinkedList_GetTotal( &rlist );
		DEBUG_MSG("proc invalid area, m = %d\n", m);
		LinkedList_Goto( &rlist, 0 );
		/* 在 surface 上逐个重绘无效区域 */
		for( j=0; j<m; ++j ) {
			p_rect = (LCUI_Rect*)LinkedList_Get( &rlist );
			paint = Surface_BeginPaint( p_sr->surface, p_rect );
			DEBUG_MSG( "[%s]: render rect: (%d,%d,%d,%d), %d\n", p_sr->widget->type, paint->rect.left, paint->rect.top, paint->rect.w, paint->rect.h, j );
			Widget_Render( p_sr->widget, paint );
			Surface_EndPaint( p_sr->surface, paint );
			LinkedList_Delete( &rlist );
		}
		if( m > 0 ) {
			Surface_Present( p_sr->surface );
		}
	}

	LinkedList_Destroy( &rlist );
}
Ejemplo n.º 8
0
Archivo: event.c Proyecto: aem3372/LCUI
/** 派发当前待处理的事件至对应的处理器 */
int $(Dispatch)( LCUI_EventBox box )
{
	int i, n;
	LCUI_Event *e;
	LinkedList *elist;
	
	box->current = box->current ? 0:1;
	elist = &box->events[box->current ? 0:1];
	n = LinkedList_GetTotal( elist );
	LinkedList_Goto( elist, 0 );
	for( i=0; i<n; ++i ) {
		e = (LCUI_Event*)LinkedList_Get( elist );
		$(Send)( box, e->name, e->data );
		e->destroy_data ? e->destroy_data( e->data ):0;
		LinkedList_Goto( elist, 0 );
		LinkedList_Delete( elist );
	}
	box->current = box->current ? 0:1;
	return 0;
}
Ejemplo n.º 9
0
/** 将指定标签的样式数据从队列中删除,只删除队列尾部第一个匹配的标签 */
static void StyleTagStack_Delete( LCUI_StyleTagStack *tags, LCUI_StyleTagID tag )
{
	int i, total;
	LCUI_StyleTagData *p; 
	 
	total = LinkedList_GetTotal( tags );
	DEBUG_MSG("delete start, total tag: %d\n", total);
	if(total <= 0) {
		return;
	}
	for(i=total-1; i>=0; --i) {
		LinkedList_Goto( tags, i );
		p = (LCUI_StyleTagData*)LinkedList_Get( tags );
		if( p->tag_id == tag ) {
			LinkedList_Delete( tags );
			break;
		}
	} 
	DEBUG_MSG("delete end, total tag: %d\n", LinkedList_GetTotal( tags ));
}
Ejemplo n.º 10
0
/** 派发当前待处理的事件至对应的处理器 */
int $(Dispatch)( LCUI_EventBox box )
{
	int i, n;
	LCUI_Event *e;
	LinkedList *elist;

	elist = &box->events[box->current];
	box->current = box->current ? 0:1;
	n = LinkedList_GetTotal( elist );
	LinkedList_Goto( elist, 0 );
	DEBUG_MSG("event total: %d\n", n);
	for( i=0; i<n; ++i ) {
		e = (LCUI_Event*)LinkedList_Get( elist );
		$(Send)( box, e->name, e->data );
		e->destroy_data ? e->destroy_data( e->data ):0;
		e->data = NULL;
		LinkedList_Goto( elist, 0 );
		LinkedList_Delete( elist );
	}
	DEBUG_MSG("quit\n");
	return 0;
}
Ejemplo n.º 11
0
/** 从程序任务队列中删除有指定回调函数的任务 */
int LCUI_RemoveTask( CallBackFunc task_func, LCUI_BOOL need_lock )
{
	int n;
	LCUI_Task *exist_task;

	if( need_lock ) {
		LCUIMutex_Lock( &MainApp.task_list_mutex );
	}
	n = LinkedList_GetTotal( &MainApp.task_list );
	for ( ; n>0; --n ) {
		exist_task = (LCUI_Task*)LinkedList_Get( &MainApp.task_list );
		if( exist_task && exist_task->func == task_func ) {
			LinkedList_Delete( &MainApp.task_list );
		} else {
			LinkedList_ToNext( &MainApp.task_list );
		}
	}
	if( need_lock ) {
		LCUIMutex_Unlock( &MainApp.task_list_mutex );
	}
	return n;
}
Ejemplo n.º 12
0
static int _Widget_ProcInvalidArea( LCUI_Widget w, LCUI_BOOL is_root, int x, int y,
			LCUI_Rect *valid_box, LCUI_DirtyRectList *rlist )
{
	int i, n, count;
	LCUI_Widget child;
	LCUI_Rect rect, child_box, *r;

	count = n = LinkedList_GetTotal( &w->dirty_rects );
	/* 取出当前记录的脏矩形 */
	for( i=0; i<n; ++i ) {
		LinkedList_Goto( &w->dirty_rects, 0 );
		r = (LCUI_Rect*)LinkedList_Get( &w->dirty_rects );
		/* 若有独立位图缓存,则重绘脏矩形区域 */
		if( Graph_IsValid(&w->graph) ) {
			LCUI_PaintContextRec_ paint;
			paint.rect = *r;
			Graph_Quote( &paint.canvas, &w->graph, &paint.rect );
			Widget_OnPaint( w, &paint );
		}
		/* 转换为相对于父部件的坐标 */
		rect.x = r->x;
		rect.y = r->y;
		/* 如果当前是根部件,则不用加上自身坐标 */
		if( !is_root ) {
			rect.x += w->base.box.graph.x;
			rect.y += w->base.box.graph.y;
		}
		rect.w = r->w;
		rect.h = r->h;
		/* 取出与容器内有效区域相交的区域 */
		if( LCUIRect_GetOverlayRect(&rect, valid_box, &rect) ) {
			/* 转换相对于根级部件的坐标 */
			rect.x += x;
			rect.y += y;
			DirtyRectList_Add( rlist, &rect );
		}
		LinkedList_Delete( &w->dirty_rects );
	}
	/* 若子级部件没有脏矩形记录 */
	if( !w->has_dirty_child ) {
		return count;
	}
	/* 缩小有效区域到当前部件内容框内,若没有重叠区域,则不向子级部件递归 */
	if( !LCUIRect_GetOverlayRect(valid_box, &w->base.box.content, &child_box) ) {
		return count;
	}
	/* 转换有效区域的坐标,相对于当前部件的内容框 */
	child_box.x -= w->base.box.content.x;
	child_box.y -= w->base.box.content.y;
	n = LinkedList_GetTotal( &w->children );
	/* 向子级部件递归 */
	for( i=0; i<n; ++i ) {
		child = (LCUI_Widget)LinkedList_Get( &w->children );
		if( !child->style.visible ) {
			continue;
		}
		count += _Widget_ProcInvalidArea(
			child, FALSE, child->base.box.graph.x + x,
			child->base.box.graph.y + y, &child_box, rlist
		);
	}
	return count;
}
Ejemplo n.º 13
0
/** 运行目标主循环 */
int LCUI_MainLoop_Run( LCUI_MainLoop loop )
{
	if( loop->state == STATE_RUNNING ) {
		_DEBUG_MSG("error: main-loop already running.");
		return -1;
	}
	DEBUG_MSG("loop: %p, enter\n", loop);
	loop->state = STATE_RUNNING;
	/* 将主循环记录插入至列表表头 */
	LinkedList_Goto( &MainApp.loop_list, 0 );
	LinkedList_Insert( &MainApp.loop_list, loop );
	MainApp.loop = loop;
	LCUIMutex_Lock( &MainApp.loop_changed );
	/* 广播,让其它线程交出主循环运行权 */
	LCUICond_Broadcast( &MainApp.loop_cond );
	/* 获取运行权 */
	LCUIMutex_Lock( &MainApp.loop_mutex );
	LCUIMutex_Unlock( &MainApp.loop_changed );
	loop->tid = LCUIThread_SelfID();
	while( loop->state != STATE_EXITED ) {
		if( LinkedList_GetTotal(&MainApp.task_list) <= 0 ) {
			DEBUG_MSG("loop: %p, sleeping...\n", loop);
			LCUICond_TimedWait( &MainApp.loop_cond, 1000 );
			DEBUG_MSG("loop: %p, wakeup\n", loop);
			/** 如果当前运行的主循环不是自己 */
			if( MainApp.loop != loop ) {
				loop->state = STATE_PAUSED;
				DEBUG_MSG("loop: %p, release control.\n", loop);
				LCUIMutex_Unlock( &MainApp.loop_mutex );
				/* 等待其它线程获得主循环运行权 */
				LCUIMutex_Lock( &MainApp.loop_changed );
				LCUIMutex_Unlock( &MainApp.loop_changed );
				DEBUG_MSG("loop: %p, waiting...\n", loop);
				/* 等待其它线程释放主循环运行权 */
				LCUIMutex_Lock( &MainApp.loop_mutex );
			}
			continue;
		}
		DEBUG_MSG("loop: %p, run task.\n", loop);
		LCUI_RunTask();
	}
	loop->state = STATE_EXITED;
	LinkedList_Goto( &MainApp.loop_list, 0 );
	LinkedList_Delete( &MainApp.loop_list );
	/* 获取处于列表表头的主循环 */
	loop = (LCUI_MainLoop)LinkedList_Get( &MainApp.loop_list );
	if( loop ) {
		/* 改变当前运行的主循环 */
		MainApp.loop = loop;
		LCUICond_Broadcast( &MainApp.loop_cond );
	}
	/* 释放运行权 */
	LCUIMutex_Unlock( &MainApp.loop_mutex );
	/* 如果列表为空,一般意味着LCUI需要退出了 */
	if( LinkedList_GetTotal( &MainApp.loop_list ) <= 0 ) {
		/** 广播,通知相关线程开始进行清理操作 */
		LCUICond_Broadcast( &MainApp.loop_list_empty );
	}
	DEBUG_MSG("loop: %p, exit\n", loop);
	return 0;
}