Ejemplo n.º 1
0
/** 将 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 );
}
Ejemplo n.º 2
0
void Widget_UpdateOpacity(LCUI_Widget w)
{
	float opacity = 1.0;
	LCUI_Style s = &w->style->sheet[key_opacity];
	if (s->is_valid) {
		switch (s->type) {
		case LCUI_STYPE_VALUE:
			opacity = 1.0f * s->value;
			break;
		case LCUI_STYPE_SCALE:
			opacity = s->val_scale;
			break;
		default:
			opacity = 1.0f;
			break;
		}
		if (opacity > 1.0) {
			opacity = 1.0;
		} else if (opacity < 0.0) {
			opacity = 0.0;
		}
	}
	w->computed_style.opacity = opacity;
	Widget_InvalidateArea(w, NULL, SV_GRAPH_BOX);
	DEBUG_MSG("opacity: %0.2f\n", opacity);
}
Ejemplo n.º 3
0
void Widget_Destroy(LCUI_Widget w)
{
	LCUI_Widget root = w;

	assert(w->state != LCUI_WSTATE_DELETED);
	while (root->parent) {
		root = root->parent;
	}
	/* If this widget is not mounted in the root widget tree */
	if (root != LCUIWidget.root) {
		w->state = LCUI_WSTATE_DELETED;
		Widget_ExecDestroy(w);
		return;
	}
	if (w->parent) {
		LCUI_Widget child;
		LinkedListNode *node;

		/* Update the index of the siblings behind it */
		node = w->node.next;
		while (node) {
			child = node->data;
			child->index -= 1;
			node = node->next;
		}
		if (w->computed_style.position != SV_ABSOLUTE) {
			Widget_UpdateLayout(w->parent);
		}
		Widget_InvalidateArea(w, NULL, SV_GRAPH_BOX);
		Widget_AddToTrash(w);
	}
}
Ejemplo n.º 4
0
void Widget_UpdateVisibility(LCUI_Widget w)
{
	LCUI_Style s = &w->style->sheet[key_visibility];
	LCUI_BOOL visible = w->computed_style.visible;

	if (w->computed_style.display == SV_NONE) {
		w->computed_style.visible = FALSE;
	} else if (s->is_valid && s->type == LCUI_STYPE_STRING &&
		   strcmp(s->val_string, "hidden") == 0) {
		w->computed_style.visible = FALSE;
	} else {
		w->computed_style.visible = TRUE;
	}
	if (visible == w->computed_style.visible) {
		return;
	}
	if (w->parent) {
		Widget_InvalidateArea(w, NULL, SV_GRAPH_BOX);
	}
	visible = w->computed_style.visible;
	if (visible) {
		Widget_PostSurfaceEvent(w, LCUI_WEVENT_SHOW, TRUE);
	} else {
		Widget_PostSurfaceEvent(w, LCUI_WEVENT_HIDE, TRUE);
	}
}
Ejemplo n.º 5
0
/** 将 widget 与 sruface 进行绑定 */
static void LCUIDisplay_BindSurface( LCUI_Widget widget )
{
	SurfaceRecord *p_sr;
	LCUI_Rect *p_rect;
	if( LCUIDisplay_GetBindSurface(widget) ) {
		return;
	}
	p_sr = (SurfaceRecord*)LinkedList_Alloc( &display.surfaces );
	p_sr->widget = widget;
	/**
	 * 初次调用 Surface_New() 耗时较长, 所以先为 p_sr->surface 设置初
	 * 始值,避免在 Surface_New() 返回前被当成正常指针使用。
	 */
	p_sr->surface = NULL;
	p_sr->surface = Surface_New();
	Surface_SetCaptionW( p_sr->surface, widget->title );
	p_rect = &widget->base.box.graph;
	Surface_Move( p_sr->surface, p_rect->x, p_rect->y );
	Surface_Resize( p_sr->surface, p_rect->w, p_rect->h );
	if( widget->style.visible ) {
		Surface_Show( p_sr->surface );
	} else {
		Surface_Hide( p_sr->surface );
	}
	Widget_InvalidateArea( widget, NULL, SV_GRAPH_BOX );
}
Ejemplo n.º 6
0
/** 响应顶级部件的各种事件 */
static void OnTopLevelWidgetEvent( LCUI_Widget w, LCUI_WidgetEvent *e, void *arg )
{
	int e_type = *((int*)&arg);
	LCUI_Surface surface;
	LCUI_Rect *p_rect;

	DEBUG_MSG("tip, e_type = %d\n", e_type);
	surface = LCUIDisplay_GetBindSurface( e->target );
	if( display.mode == LDM_SEAMLESS ) {
		if( !surface && e_type != WET_ADD ) {
			return;
		}
	} else if ( e->target == LCUIRootWidget ) {
		if( !surface && e_type != WET_ADD ) {
			return;
		}
	} else {
		return;
	}
	p_rect = &e->target->base.box.graph;
	switch( e_type ) {
	case WET_ADD:
		LCUIDisplay_BindSurface( e->target );
		break;
	case WET_REMOVE:
	case WET_DESTROY:
		LCUIDisplay_UnbindSurface( e->target );
		break;
	case WET_SHOW:
		Surface_Show( surface );
		break;
	case WET_HIDE:
		Surface_Hide( surface );
		break;
	case WET_TITLE:
		//_DEBUG_MSG("%S\n", e->target->title );
		Surface_SetCaptionW( surface, e->target->title );
		break;
	case WET_RESIZE:
		DEBUG_MSG( "resize, w: %d, h: %d\n", p_rect->w, p_rect->h );
		Surface_Resize( surface, p_rect->w, p_rect->h );
		Widget_InvalidateArea( w, NULL, SV_GRAPH_BOX );
		if( w == LCUIRootWidget && display.mode != LDM_SEAMLESS ) {
			LCUIDisplay_ExecResize( p_rect->w, p_rect->h );
		}
		break;
	case WET_MOVE:
		DEBUG_MSG( "x: %d, y: %d\n", p_rect->left, p_rect->top );
		Surface_Move( surface, p_rect->left, p_rect->top );
		break;
	default: break;
	}
}
Ejemplo n.º 7
0
/** 在 surface 主动产生无效区域的时候 */
static void OnInvalidRect( LCUI_Surface surface, LCUI_Rect *rect )
{
	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->surface != surface ) {
			continue;
		}
		Widget_InvalidateArea( p_sr->widget, rect, SV_GRAPH_BOX );
		continue;
	}
}
Ejemplo n.º 8
0
void Widget_Empty(LCUI_Widget w)
{
	LCUI_Widget root = w;

	while (root->parent) {
		root = root->parent;
	}
	if (root == LCUIWidget.root) {
		LinkedListNode *next, *node;
		node = w->children.head.next;
		while (node) {
			next = node->next;
			Widget_AddToTrash(node->data);
			node = next;
		}
		Widget_InvalidateArea(w, NULL, SV_GRAPH_BOX);
		Widget_AddTask(w, LCUI_WTASK_LAYOUT);
	} else {
		Widget_DestroyChildren(w);
	}
}
Ejemplo n.º 9
0
/** 处理刷新(标记整个部件区域为脏矩形) */
static void HandleRefresh(LCUI_Widget w)
{
	DEBUG_MSG("refresh\n");
	Widget_InvalidateArea(w, NULL, SV_GRAPH_BOX);
}
Ejemplo n.º 10
0
/** 处理主体刷新(标记主体区域为脏矩形,但不包括阴影区域) */
static void HandleBody(LCUI_Widget w)
{
	Widget_InvalidateArea(w, NULL, SV_BORDER_BOX);
}
Ejemplo n.º 11
0
void Widget_UpdatePosition(LCUI_Widget w)
{
	LCUI_RectF rect;
	int position = ComputeStyleOption(w, key_position, SV_STATIC);
	int valign = ComputeStyleOption(w, key_vertical_align, SV_TOP);
	w->computed_style.vertical_align = valign;
	w->computed_style.left = ComputeXMetric(w, key_left);
	w->computed_style.right = ComputeXMetric(w, key_right);
	w->computed_style.top = ComputeYMetric(w, key_top);
	w->computed_style.bottom = ComputeYMetric(w, key_bottom);
	if (w->parent && w->computed_style.position != position) {
		w->computed_style.position = position;
		Widget_UpdateLayout(w->parent);
		Widget_ClearComputedSize(w);
		Widget_UpdateChildrenSize(w);
		/* 当部件尺寸是按百分比动态计算的时候需要重新计算尺寸 */
		if (Widget_CheckStyleType(w, key_width, scale) ||
		    Widget_CheckStyleType(w, key_height, scale)) {
			Widget_UpdateSize(w);
		}
	}
	w->computed_style.position = position;
	Widget_UpdateZIndex(w);
	rect = w->box.canvas;
	w->x = w->origin_x;
	w->y = w->origin_y;
	switch (position) {
	case SV_ABSOLUTE:
		w->x = w->y = 0;
		if (!Widget_HasAutoStyle(w, key_left)) {
			w->x = w->computed_style.left;
		} else if (!Widget_HasAutoStyle(w, key_right)) {
			if (w->parent) {
				w->x = w->parent->box.border.width;
				w->x -= w->width;
			}
			w->x -= w->computed_style.right;
		}
		if (!Widget_HasAutoStyle(w, key_top)) {
			w->y = w->computed_style.top;
		} else if (!Widget_HasAutoStyle(w, key_bottom)) {
			if (w->parent) {
				w->y = w->parent->box.border.height;
				w->y -= w->height;
			}
			w->y -= w->computed_style.bottom;
		}
		break;
	case SV_RELATIVE:
		if (!Widget_HasAutoStyle(w, key_left)) {
			w->x += w->computed_style.left;
		} else if (!Widget_HasAutoStyle(w, key_right)) {
			w->x -= w->computed_style.right;
		}
		if (!Widget_HasAutoStyle(w, key_top)) {
			w->y += w->computed_style.top;
		} else if (!Widget_HasAutoStyle(w, key_bottom)) {
			w->y -= w->computed_style.bottom;
		}
	default:
		if (w->parent) {
			w->x += w->parent->padding.left;
			w->y += w->parent->padding.top;
		}
		break;
	}
	switch (valign) {
	case SV_MIDDLE:
		if (!w->parent) {
			break;
		}
		w->y += (w->parent->box.content.height - w->height) / 2;
		break;
	case SV_BOTTOM:
		if (!w->parent) {
			break;
		}
		w->y += w->parent->box.content.height - w->height;
	case SV_TOP:
	default:
		break;
	}
	w->box.outer.x = w->x;
	w->box.outer.y = w->y;
	w->x += w->margin.left;
	w->y += w->margin.top;
	/* 以x、y为基础 */
	w->box.padding.x = w->x;
	w->box.padding.y = w->y;
	w->box.border.x = w->x;
	w->box.border.y = w->y;
	w->box.canvas.x = w->x;
	w->box.canvas.y = w->y;
	/* 计算各个框的坐标 */
	w->box.padding.x += w->computed_style.border.left.width;
	w->box.padding.y += w->computed_style.border.top.width;
	w->box.content.x = w->box.padding.x + w->padding.left;
	w->box.content.y = w->box.padding.y + w->padding.top;
	w->box.canvas.x -= Widget_GetBoxShadowOffsetX(w);
	w->box.canvas.y -= Widget_GetBoxShadowOffsetY(w);
	if (w->parent) {
		/* 标记移动前后的区域 */
		Widget_InvalidateArea(w, NULL, SV_GRAPH_BOX);
		Widget_InvalidateArea(w->parent, &rect, SV_PADDING_BOX);
	}
	/* 检测是否为顶级部件并做相应处理 */
	Widget_PostSurfaceEvent(w, LCUI_WEVENT_MOVE, TRUE);
}
Ejemplo n.º 12
0
void Widget_UpdateSize(LCUI_Widget w)
{
	int box_sizing;
	LCUI_RectF rect = w->box.canvas;
	LCUI_Rect2F padding = w->padding;

	box_sizing = ComputeStyleOption(w, key_box_sizing, SV_CONTENT_BOX);
	w->computed_style.box_sizing = box_sizing;
	Widget_ComputePadding(w);
	Widget_ComputeSize(w);
	/* 如果左右外间距是 auto 类型的,则需要计算外间距 */
	if (w->style->sheet[key_margin_left].is_valid &&
	    w->style->sheet[key_margin_left].type == LCUI_STYPE_AUTO) {
		Widget_UpdateMargin(w);
	} else if (w->style->sheet[key_margin_right].is_valid &&
		   w->style->sheet[key_margin_right].type == LCUI_STYPE_AUTO) {
		Widget_UpdateMargin(w);
	}
	/* 若尺寸无变化则不继续处理 */
	if (rect.width == w->box.canvas.width &&
	    rect.height == w->box.canvas.height &&
	    padding.top == w->padding.top &&
	    padding.right == w->padding.right &&
	    padding.bottom == w->padding.bottom &&
	    padding.left == w->padding.left) {
		return;
	}
	/* 若在变化前后的宽高中至少有一个为 0,则不继续处理 */
	if ((w->box.canvas.width <= 0 || w->box.canvas.height <= 0) &&
	    (rect.width <= 0 || rect.height <= 0)) {
		return;
	}
	Widget_UpdateLayout(w);
	/* 如果垂直对齐方式不为顶部对齐 */
	if (w->computed_style.vertical_align != SV_TOP) {
		Widget_UpdatePosition(w);
	} else if (w->computed_style.position == SV_ABSOLUTE) {
		/* 如果是绝对定位,且指定了右间距或底间距 */
		if (!Widget_HasAutoStyle(w, key_right) ||
		    !Widget_HasAutoStyle(w, key_bottom)) {
			Widget_UpdatePosition(w);
		}
	}
	if (w->parent) {
		/* Mark old area and new area need to repaint */
		Widget_InvalidateArea(w->parent, &rect, SV_PADDING_BOX);
		rect.width = w->box.canvas.width;
		rect.height = w->box.canvas.height;
		Widget_InvalidateArea(w->parent, &rect, SV_PADDING_BOX);
		/* If its width depends on the parent, there is no need to
		 * repeatedly update the parent size and layout.
		 * See Widget_ComputeStaticSize() for more details. */
		if (!Widget_HasParentDependentWidth(w)) {
			if (Widget_HasAutoStyle(w->parent, key_width) ||
			    Widget_HasAutoStyle(w->parent, key_height)) {
				Widget_AddTask(w->parent, LCUI_WTASK_RESIZE);
			}
			if (w->computed_style.display != SV_NONE &&
			    w->computed_style.position == SV_STATIC) {
				Widget_UpdateLayout(w->parent);
			}
		}
	}
	Widget_SendResizeEvent(w);
	Widget_UpdateChildrenSize(w);
}