Пример #1
0
/**
 * 功能:取消指定部件的焦点
 * 说明:该部件会得到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;
}
Пример #2
0
/** 获取指定部件内的已获得焦点的子部件 */
LCUI_API LCUI_Widget* Get_FocusWidget( LCUI_Widget *widget )
{
	int i, focus_pos, total;
	LCUI_Widget **focus_widget;
	LCUI_Queue *queue_ptr;

	//printf( "Get_FocusWidget(): widget: %p\n", widget );
	//print_widget_info( widget );
	queue_ptr = Widget_GetChildList( widget );
	if( !widget ) {
		widget = RootWidget_GetSelf();
	} else {
		/* 如果部件不需要焦点,则返回NULL */
		if( !widget->focus ) {
			return NULL;
		}
	}
	queue_ptr = &widget->child;
	focus_widget = &widget->focus_widget;

	if( !focus_widget ) {
		return NULL;
	}

	total = Queue_GetTotal( queue_ptr );
	if( total <= 0 ) {
		return NULL;
	}
	focus_pos = WidgetQueue_FindPos( queue_ptr, *focus_widget );
	if( focus_pos < 0 ) {
		*focus_widget = NULL;
		return NULL;
	}
	/* 查找可获取焦点的有效部件 */
	for( i=focus_pos; i<total; ++i ) {
		widget = (LCUI_Widget*)Queue_Get( queue_ptr, i );
		if( widget && widget->focus ) {
			break;
		}
	}
	if( i>=total ) {
		*focus_widget = NULL;
		widget = NULL;
	}

	return widget;
}
Пример #3
0
/** 复位指定部件内的子部件的焦点 */
LCUI_API LCUI_BOOL Widget_ResetFocus( LCUI_Widget* widget )
{
	LCUI_Widget** focus_widget;
	LCUI_WidgetEvent event;

	if( !widget ) {
		widget = RootWidget_GetSelf();
	}
	focus_widget = &widget->focus_widget;
	if( *focus_widget ) {
		event.type = EVENT_FOCUSOUT;
		Widget_DispatchEvent( *focus_widget, &event );
	}

	*focus_widget = NULL;
	return TRUE;
}
Пример #4
0
/**
 * 功能:为部件设置焦点
 * 说明:上个获得焦点的部件会得到EVENT_FOCUSOUT事件,而当前获得焦点的部件会得到
 * EVENT_FOCUSIN事件。
 * */
LCUI_API LCUI_BOOL Widget_SetFocus( LCUI_Widget *widget )
{
	LCUI_Widget **focus_widget;
	LCUI_WidgetEvent event;

	if( widget ) {
		/* 先处理上级部件的焦点 */
		if( widget->parent ) {
			Widget_SetFocus( widget->parent );
		}
		if( !widget->focus ) {
			return FALSE;
		}
	} else {
		return FALSE;
	}
	if( widget->parent ) {
		focus_widget = &widget->parent->focus_widget;
	} else {
		focus_widget = &RootWidget_GetSelf()->focus_widget;
	}
	if( *focus_widget ) {
		/* 若之前获得焦点的是模态部件,则不能移动焦点 */
		if( (*focus_widget)->modal ) {
			return FALSE;
		}
		/* 如果上次和这次的部件不一样 */
		if( *focus_widget != widget ) {
			event.type = EVENT_FOCUSOUT;
			Widget_DispatchEvent( *focus_widget, &event );
		}
	}
	event.type = EVENT_FOCUSIN;
	Widget_DispatchEvent( widget, &event );
	/* 保存新焦点位置 */
	*focus_widget = widget;
	return TRUE;
}
Пример #5
0
LCUI_API void WidgetMsg_Proc( LCUI_Widget *widget )
{
	int i,n;
	WidgetMsgData *data_ptr;
	LCUI_Widget *child;
	LCUI_Queue *msg_buff, *child_list;
	
	if( widget == NULL ) {
		widget = RootWidget_GetSelf();
	}
	msg_buff = Widget_GetMsgBuff( widget );
	child_list = Widget_GetChildList( widget );
	
	Queue_Lock( msg_buff );
	n = Queue_GetTotal( msg_buff );
	for(i=0; i<n; ++i) {
		DEBUG_MSG("[%d/%d]get msg\n", i, n);
		data_ptr = (WidgetMsgData*)Queue_Get( msg_buff, i );
		DEBUG_MSG("[%d/%d]dispatch msg\n", i, n);
		if( WidgetMsg_Dispatch( widget, data_ptr ) ) {
			DEBUG_MSG("[%d/%d]delete msg\n", i, n);
			Queue_Delete( msg_buff, i );
			n = Queue_GetTotal( msg_buff );
			--i;
		}
		DEBUG_MSG("[%d/%d]skip msg\n", i, n);
	}
	Queue_Unlock( msg_buff );
	n = Queue_GetTotal( child_list );
	/* 从尾到首,递归处理子部件的更新 */
	while(n--) {
		child = (LCUI_Widget*)Queue_Get( child_list, n );
		if( child ) {
			DEBUG_MSG("proc child msg\n");
			WidgetMsg_Proc( child );
		}
	}
}
Пример #6
0
/** 判断指定部件是否被允许响应事件 */
LCUI_API LCUI_BOOL Widget_IsAllowResponseEvent( LCUI_Widget *widget )
{
	int i, n;
	LCUI_Queue *child_list;
	LCUI_Widget *child, *root_widget, *up_widget;

	root_widget = RootWidget_GetSelf();
	if( widget == NULL || widget == root_widget ) {
		return TRUE;
	}
	/* 开始判断该部件的上级部件 */
	up_widget = widget->parent;
	while( widget && widget != root_widget ) {
		child_list = Widget_GetChildList( up_widget );
		n = Queue_GetTotal( child_list );
		for(i=0; i<n; ++i) {
			child = (LCUI_Widget*)Queue_Get( child_list, i );
			if( !child || !child->visible ) {
				continue;
			}
			if( child == widget ) {
				break;
			}
			if( child->modal ) {
				return FALSE;
			}
		}
		/* 记录这一级部件 */
		widget = up_widget;
		if( widget ) {
			/* 切换至上级部件 */
			up_widget = widget->parent;
		}
	}
	return TRUE;
}
Пример #7
0
LCUI_API int WidgetMsg_Post(	LCUI_Widget *widget,
				uint_t msg_id,
				void *data,
				LCUI_BOOL only_one,
				LCUI_BOOL need_free )
{
	int i, total, n_found, ret = 0;
	WidgetMsgData tmp_msg, *tmp_msg_ptr;
	LCUI_Queue *des_queue;

	if( !widget ) {
		return -1;
	}
	tmp_msg.msg_id = msg_id;
	tmp_msg.need_free = need_free;
	tmp_msg.target = widget;
	if( data ) {
		tmp_msg.valid = TRUE;
	} else {
		tmp_msg.valid = FALSE;
	}
	switch(tmp_msg.msg_id) {
	    case WIDGET_MOVE:
		if(tmp_msg.valid) {
			tmp_msg.data.pos = *((LCUI_Pos*)data);
		}
		break;
	    case WIDGET_RESIZE:
		if(tmp_msg.valid) {
			tmp_msg.data.size = *((LCUI_Size*)data);
		}
		break;
	    case WIDGET_CHGSTATE:
		if(tmp_msg.valid) {
			tmp_msg.data.state = *((int*)data);
		}
		break;
	    case WIDGET_PAINT:
	    case WIDGET_REFRESH:
	    case WIDGET_UPDATE:
	    case WIDGET_SORT:
		tmp_msg.valid = FALSE;
		break;
		/* 部件的显示、隐藏和销毁消息,需要发送到父部件 */
	    case WIDGET_SHOW:
	    case WIDGET_HIDE:
	    case WIDGET_DESTROY:
		/* 如果不是根部件 */
		if( widget != RootWidget_GetSelf() ) {
			widget = widget->parent;
		} 
		tmp_msg.valid = FALSE;
		break;
	    default:
		tmp_msg.data.ptr = data;
		break;
	}
	des_queue = Widget_GetMsgBuff( widget );
	total = Queue_GetTotal( des_queue );
	for(n_found=0,i=0; i<total; ++i) {
		tmp_msg_ptr = (WidgetMsgData*)Queue_Get( des_queue, i );
		if( !tmp_msg_ptr ) {
			continue;
		}
		if(tmp_msg_ptr->valid != tmp_msg.valid
		|| tmp_msg_ptr->msg_id != tmp_msg.msg_id
		|| tmp_msg_ptr->target != tmp_msg.target ) {
			continue;
		}
		++n_found;
		/* 如果已存在的数量少于2 */
		if( !only_one && n_found < 2 ) {
			continue;
		}
		/* 否则,需要进行替换 */
		switch(tmp_msg.msg_id) {
		    case WIDGET_MOVE:
			if(tmp_msg.valid) {
				tmp_msg_ptr->data.pos = tmp_msg.data.pos;
				tmp_msg_ptr->valid = TRUE;
			} else {
				tmp_msg_ptr->valid = FALSE;
			}
			break;
		    case WIDGET_RESIZE:
			if(tmp_msg.valid) {
				tmp_msg_ptr->data.size = tmp_msg.data.size;
				tmp_msg_ptr->valid = TRUE;
			} else {
				tmp_msg_ptr->valid = FALSE;
			}
			break;
		    case WIDGET_CHGSTATE:
			if(tmp_msg.valid) {
				tmp_msg_ptr->data.state = tmp_msg.data.state;
			} else {
				tmp_msg_ptr->valid = FALSE;
			}
			break;
		    case WIDGET_PAINT:
		    case WIDGET_REFRESH:
		    case WIDGET_HIDE:
		    case WIDGET_UPDATE:
		    case WIDGET_SHOW:
		    case WIDGET_SORT:
			tmp_msg.valid = FALSE;
			break;
		    default:
			if( tmp_msg_ptr->need_free ) {
				free( tmp_msg_ptr->data.ptr );
			}
			tmp_msg_ptr->need_free = tmp_msg.need_free;
			tmp_msg_ptr->data.ptr = tmp_msg.data.ptr;
			break;
		}
		break;
	}
	/* 未找到,则添加新的 */
	if( i>= total ) {
		ret = Queue_Add( des_queue, &tmp_msg );
	}
	return ret;
}