/** * 功能:取消指定部件的焦点 * 说明:该部件会得到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; }
/** 获取指定部件内的已获得焦点的子部件 */ 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; }
/** 复位指定部件内的子部件的焦点 */ 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; }
/** * 功能:为部件设置焦点 * 说明:上个获得焦点的部件会得到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; }
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 ); } } }
/** 判断指定部件是否被允许响应事件 */ 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; }
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; }