Exemple #1
0
static void a3d_layer_layout(a3d_widget_t* widget,
                             int dragx, int dragy)
{
	assert(widget);
	LOGD("debug dragx=%i, dragy=%i", dragx, dragy);

	// the rect_clip is constant across all layers
	a3d_rect4f_t rect_clip;
	a3d_rect4f_intersect(&widget->rect_draw,
	                     &widget->rect_clip,
	                     &rect_clip);

	a3d_layer_t*    self = (a3d_layer_t*) widget;
	a3d_listitem_t* iter = a3d_list_head(self->list);
	while(iter)
	{
		a3d_widget_t* child = (a3d_widget_t*) a3d_list_peekitem(iter);

		// layout the layer
		float x = 0.0f;
		float y = 0.0f;
		a3d_widget_anchorPt(&widget->rect_draw,
		                    child->anchor,
		                    &x, &y);
		a3d_widget_layoutXYClip(child, x, y, &rect_clip,
		                        dragx, dragy);

		iter = a3d_list_next(iter);
	}
}
Exemple #2
0
static void a3d_bulletbox_layout(a3d_widget_t* widget,
                                 int dragx, int dragy)
{
	assert(widget);

	a3d_bulletbox_t* self = (a3d_bulletbox_t*) widget;
	a3d_widget_t*    icon = (a3d_widget_t*) self->icon;
	a3d_widget_t*    text = (a3d_widget_t*) self->text;

	// initialize the layout
	float x  = 0.0f;
	float y  = 0.0f;
	float t  = widget->rect_draw.t;
	float l  = widget->rect_draw.l;
	float h  = widget->rect_draw.h;
	float iw = icon->rect_border.w;
	float tw = text->rect_border.w;

	// layout icon
	a3d_rect4f_t rect_draw;
	rect_draw.t = t;
	rect_draw.l = l;
	rect_draw.w = iw;
	rect_draw.h = h;
	a3d_rect4f_t rect_clip;
	a3d_widget_anchorPt(&rect_draw, icon->anchor, &x, &y);
	a3d_rect4f_intersect(&rect_draw,
	                     &widget->rect_clip,
	                     &rect_clip);
	a3d_widget_layoutXYClip(icon, x, y, &rect_clip,
	                        dragx, dragy);

	// layout text
	rect_draw.l = l + A3D_BULLETBOX_SPACE*iw;
	rect_draw.w = tw;
	a3d_widget_anchorPt(&rect_draw, text->anchor, &x, &y);
	a3d_rect4f_intersect(&rect_draw,
	                     &widget->rect_clip,
	                     &rect_clip);
	a3d_widget_layoutXYClip(text, x, y, &rect_clip,
	                        dragx, dragy);
}
Exemple #3
0
static void a3d_listbox_layoutHorizontalStretch(a3d_listbox_t* self,
                                                int dragx, int dragy)
{
	assert(self);
	LOGD("debug dragx=%i, dragy=%i", dragx, dragy);

	// initialize the layout
	float x   = 0.0f;
	float y   = 0.0f;
	float t   = self->widget.rect_draw.t;
	float l   = self->widget.rect_draw.l;
	float w   = self->widget.rect_draw.w;
	float h   = self->widget.rect_draw.h;
	float cnt = (float) a3d_list_size(self->list);
	float dw  = w/cnt;
	a3d_rect4f_t rect_clip;
	a3d_rect4f_t rect_draw;

	a3d_listitem_t* iter = a3d_list_head(self->list);
	while(iter)
	{
		a3d_widget_t* child = (a3d_widget_t*) a3d_list_peekitem(iter);

		rect_draw.t = t;
		rect_draw.l = l;
		rect_draw.w = dw;
		rect_draw.h = h;
		l += dw;

		a3d_widget_anchorPt(&rect_draw, child->anchor, &x, &y);
		a3d_rect4f_intersect(&rect_draw,
		                     &self->widget.rect_clip,
		                     &rect_clip);
		a3d_widget_layoutXYClip(child, x, y, &rect_clip,
		                        dragx, dragy);

		iter = a3d_list_next(iter);
	}
}
Exemple #4
0
static void a3d_listbox_layoutVerticalShrink(a3d_listbox_t* self,
                                             int dragx, int dragy)
{
	assert(self);
	LOGD("debug dragx=%i, dragy=%i", dragx, dragy);

	// initialize the layout
	float x = 0.0f;
	float y = 0.0f;
	float t = self->widget.rect_draw.t;
	float l = self->widget.rect_draw.l;
	float w = self->widget.rect_draw.w;
	a3d_rect4f_t rect_clip;
	a3d_rect4f_t rect_draw;

	a3d_listitem_t* iter = a3d_list_head(self->list);
	while(iter)
	{
		a3d_widget_t* child = (a3d_widget_t*) a3d_list_peekitem(iter);
		float h = child->rect_border.h;

		rect_draw.t = t;
		rect_draw.l = l;
		rect_draw.w = w;
		rect_draw.h = h;
		t += h;

		a3d_widget_anchorPt(&rect_draw, child->anchor, &x, &y);
		a3d_rect4f_intersect(&rect_draw,
		                     &self->widget.rect_clip,
		                     &rect_clip);
		a3d_widget_layoutXYClip(child, x, y, &rect_clip,
		                        dragx, dragy);

		iter = a3d_list_next(iter);
	}
}
Exemple #5
0
static void a3d_hline_draw(a3d_widget_t* widget)
{
	assert(widget);

	a3d_hline_t* self = (a3d_hline_t*) widget;

	// clip separator to border
	a3d_rect4f_t rect_border_clip;
	if(a3d_rect4f_intersect(&widget->rect_border,
	                        &widget->rect_clip,
	                        &rect_border_clip) == 0)
	{
		return;
	}

	// clip separator
	float top = widget->rect_clip.t;
	float h2  = widget->rect_clip.h/2.0f;

	a3d_rect4f_t line =
	{
		.t = top + h2,
		.l = rect_border_clip.l,
		.w = rect_border_clip.w,
		.h = 0.0f
	};

	// draw the separator
	a3d_screen_t* screen = widget->screen;
	a3d_vec4f_t*  c      = &self->color;
	float         alpha  = widget->fade*c->a;
	if(alpha > 0.0f)
	{
		glDisable(GL_SCISSOR_TEST);
		if(alpha < 1.0f)
		{
			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		}
		glUseProgram(screen->prog);
		glEnableVertexAttribArray(screen->attr_coords);

		int line_style = A3D_WIDGET_LINE_MEDIUM;
		if(self->style == A3D_HLINE_STYLE_SMALL)
		{
			line_style = A3D_WIDGET_LINE_SMALL;
		}
		else if(self->style == A3D_HLINE_STYLE_LARGE)
		{
			line_style = A3D_WIDGET_LINE_LARGE;
		}

		float lw = a3d_screen_layoutLine(screen, line_style);
		glLineWidth(lw);

		a3d_rect4f_t* r = &line;
		glBindBuffer(GL_ARRAY_BUFFER, screen->id_coords2);
		glVertexAttribPointer(screen->attr_coords, 2, GL_FLOAT, GL_FALSE, 0, 0);
		a3d_mat4f_t mvp;
		a3d_mat4f_ortho(&mvp, 1, 0.0f, screen->w, screen->h, 0.0f, 0.0f, 2.0f);
		glUniformMatrix4fv(screen->unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp);
		glUniform4f(screen->unif_rect, r->t, r->l, r->w, r->h);
		glUniform4f(screen->unif_color, c->r, c->g, c->b, alpha);
		glDrawArrays(GL_LINES, 0, 2);

		glLineWidth(1.0f);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glDisableVertexAttribArray(screen->attr_coords);
		glUseProgram(0);
		if(alpha < 1.0f)
		{
			glDisable(GL_BLEND);
		}
		glEnable(GL_SCISSOR_TEST);
	}
}

/***********************************************************
* public                                                   *
***********************************************************/

a3d_hline_t* a3d_hline_new(a3d_screen_t* screen,
                           int wsize,
                           int anchor,
                           int style_line,
                           a3d_vec4f_t* color_line,
                           int max_len)
{
	assert(screen);
	assert(color_line);

	a3d_vec4f_t clear =
	{
		.r = 0.0f,
		.g = 0.0f,
		.b = 0.0f,
		.a = 0.0f
	};

	if(wsize == 0)
	{
		wsize = sizeof(a3d_hline_t);
	}

	a3d_hline_t* self = (a3d_hline_t*) a3d_widget_new(screen,
	                                                  wsize,
	                                                  anchor,
	                                                  A3D_WIDGET_WRAP_SHRINK,
	                                                  A3D_WIDGET_WRAP_SHRINK,
	                                                  A3D_WIDGET_STRETCH_NA,
	                                                  1.0f,
	                                                  A3D_WIDGET_BORDER_NONE,
	                                                  A3D_WIDGET_LINE_NONE,
	                                                  &clear,
	                                                  &clear,
	                                                  NULL,
	                                                  a3d_hline_size,
	                                                  NULL,
	                                                  NULL,
	                                                  NULL,
	                                                  a3d_hline_draw,
	                                                  NULL,
	                                                  NULL);
	if(self == NULL)
	{
		return NULL;
	}

	self->wrapx   = A3D_HLINE_WRAP_SHRINK;
	self->max_len = max_len;
	self->style   = style_line;
	a3d_vec4f_copy(color_line, &self->color);

	return self;
}

void a3d_hline_delete(a3d_hline_t** _self)
{
	assert(_self);

	a3d_hline_t* self = *_self;
	if(self)
	{
		a3d_widget_delete((a3d_widget_t**) _self);
	}
}
Exemple #6
0
void a3d_widget_draw(a3d_widget_t* self)
{
	assert(self);
	LOGD("debug");

	if(self->fade == 0.0f)
	{
		return;
	}

	a3d_rect4f_t rect_border_clip;
	if(a3d_rect4f_intersect(&self->rect_border,
	                        &self->rect_clip,
	                        &rect_border_clip) == 0)
	{
		return;
	}

	// draw the fill
	a3d_screen_t* screen = self->screen;
	a3d_vec4f_t*  c      = &self->color_fill;
	float         alpha  = self->fade*c->a;
	if(alpha > 0.0f)
	{
		a3d_screen_scissor(screen, &rect_border_clip);
		if(alpha < 1.0f)
		{
			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		}

		a3d_mat4f_t mvp;
		glBindBuffer(GL_ARRAY_BUFFER, self->id_vtx_rect);
		a3d_mat4f_ortho(&mvp, 1, 0.0f, screen->w, screen->h, 0.0f, 0.0f, 2.0f);

		if(self->tone_y2 == 0.0f)
		{
			glEnableVertexAttribArray(self->attr_vertex);
			glVertexAttribPointer(self->attr_vertex, 2, GL_FLOAT, GL_FALSE, 0, 0);
			glUseProgram(self->prog);
			glUniform4f(self->unif_color, c->r, c->g, c->b, alpha);
			glUniformMatrix4fv(self->unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp);
		}
		else
		{
			a3d_vec4f_t* c2     = &self->color_fill2;
			float        alpha2 = self->fade*c2->a;
			glEnableVertexAttribArray(self->attr_vertex2);
			glVertexAttribPointer(self->attr_vertex2, 2, GL_FLOAT, GL_FALSE, 0, 0);
			glUseProgram(self->prog2);
			glUniform4f(self->unif_color2a, c->r, c->g, c->b, alpha);
			glUniform4f(self->unif_color2b, c2->r, c2->g, c2->b, alpha2);
			glUniform1f(self->unif_y2, self->tone_y2);
			glUniformMatrix4fv(self->unif_mvp2, 1, GL_FALSE, (GLfloat*) &mvp);
		}
		glDrawArrays(GL_TRIANGLE_FAN, 0, 4*A3D_WIDGET_BEZEL);

		glBindBuffer(GL_ARRAY_BUFFER, 0);
		if(self->tone_y2 == 0.0f)
		{
			glDisableVertexAttribArray(self->attr_vertex);
		}
		else
		{
			glDisableVertexAttribArray(self->attr_vertex2);
		}
		glUseProgram(0);
		if(alpha < 1.0f)
		{
			glDisable(GL_BLEND);
		}
	}

	// draw the contents
	a3d_rect4f_t rect_draw_clip;
	if(a3d_rect4f_intersect(&self->rect_draw,
	                        &self->rect_clip,
	                        &rect_draw_clip))
	{
		a3d_widget_draw_fn draw_fn = self->draw_fn;
		if(draw_fn)
		{
			a3d_screen_scissor(screen, &rect_draw_clip);
			(*draw_fn)(self);
		}

		// draw the scroll bar
		float s = rect_draw_clip.h/self->rect_draw.h;
		if(self->scroll_bar && (s < 1.0f))
		{
			// clamp the start/end points
			float a = -self->drag_dy/self->rect_draw.h;
			float b = a + s;
			if(a < 0.0f)
			{
				a = 0.0f;
			}
			else if(a > 1.0f)
			{
				a = 1.0f;
			}

			if(b < 0.0f)
			{
				b = 0.0f;
			}
			else if(b > 1.0f)
			{
				b = 1.0f;
			}

			a3d_vec4f_t* c0 = &self->color_scroll0;
			a3d_vec4f_t* c1 = &self->color_scroll1;
			a3d_screen_scissor(screen, &rect_border_clip);
			if((c0->a < 1.0f) || (c1->a < 1.0f))
			{
				glEnable(GL_BLEND);
				glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			}

			a3d_mat4f_t mvp;
			glBindBuffer(GL_ARRAY_BUFFER, self->scroll_id_vtx_rect);
			a3d_mat4f_ortho(&mvp, 1, 0.0f, screen->w, screen->h, 0.0f, 0.0f, 2.0f);

			glEnableVertexAttribArray(self->scroll_attr_vertex);
			glVertexAttribPointer(self->scroll_attr_vertex, 4, GL_FLOAT, GL_FALSE, 0, 0);
			glUseProgram(self->scroll_prog);
			glUniform4f(self->scroll_unif_color0, c0->r, c0->g, c0->b, c0->a);
			glUniform4f(self->scroll_unif_color1, c1->r, c1->g, c1->b, c1->a);
			glUniform1f(self->scroll_unif_a, a);
			glUniform1f(self->scroll_unif_b, b);
			glUniformMatrix4fv(self->scroll_unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp);
			glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

			glBindBuffer(GL_ARRAY_BUFFER, 0);
			glDisableVertexAttribArray(self->scroll_attr_vertex);
			glUseProgram(0);
			if((c0->a < 1.0f) || (c1->a < 1.0f))
			{
				glDisable(GL_BLEND);
			}
		}
	}

	// draw the border
	c     = &self->color_line;
	alpha = self->fade*c->a;
	if((alpha > 0.0f) && (self->style_line != A3D_WIDGET_LINE_NONE))
	{
		glDisable(GL_SCISSOR_TEST);
		if(alpha < 1.0f)
		{
			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		}
		glUseProgram(self->prog);
		glEnableVertexAttribArray(self->attr_vertex);

		// draw rounded line
		glBindBuffer(GL_ARRAY_BUFFER, self->id_vtx_line);
		glVertexAttribPointer(self->attr_vertex, 2, GL_FLOAT, GL_FALSE, 0, 0);
		a3d_mat4f_t mvp;
		a3d_mat4f_ortho(&mvp, 1, 0.0f, screen->w, screen->h, 0.0f, 0.0f, 2.0f);
		glUniformMatrix4fv(self->unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp);
		glUniform4f(self->unif_color, c->r, c->g, c->b, alpha);
		glDrawArrays(GL_TRIANGLE_STRIP, 0, 2*(4*A3D_WIDGET_BEZEL + 1));

		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glDisableVertexAttribArray(self->attr_vertex);
		glUseProgram(0);
		if(alpha < 1.0f)
		{
			glDisable(GL_BLEND);
		}
		glEnable(GL_SCISSOR_TEST);
	}
}
Exemple #7
0
void a3d_widget_layoutXYClip(a3d_widget_t* self,
                             float x, float y,
                             a3d_rect4f_t* clip,
                             int dragx, int dragy)
{
	assert(self);
	assert(clip);
	LOGD("debug x=%f, y=%f, dragx=%i, dragy=%i", x, y, dragx, dragy);

	float w  = self->rect_border.w;
	float h  = self->rect_border.h;
	float ct = clip->t;
	float cl = clip->l;
	float cw = clip->w;
	float ch = clip->h;
	float w2 = w/2.0f;
	float h2 = h/2.0f;
	float t  = y;
	float l  = x;

	a3d_rect4f_copy(clip, &self->rect_clip);

	// anchor the widget origin
	if(self->anchor == A3D_WIDGET_ANCHOR_TC)
	{
		l = x - w2;
	}
	else if(self->anchor == A3D_WIDGET_ANCHOR_TR)
	{
		l = x - w;
	}
	else if(self->anchor == A3D_WIDGET_ANCHOR_CL)
	{
		t = y - h2;
	}
	else if(self->anchor == A3D_WIDGET_ANCHOR_CC)
	{
		t = y - h2;
		l = x - w2;
	}
	else if(self->anchor == A3D_WIDGET_ANCHOR_CR)
	{
		t = y - h2;
		l = x - w;
	}
	else if(self->anchor == A3D_WIDGET_ANCHOR_BL)
	{
		t = y - h;
	}
	else if(self->anchor == A3D_WIDGET_ANCHOR_BC)
	{
		t = y - h;
		l = x - w2;
	}
	else if(self->anchor == A3D_WIDGET_ANCHOR_BR)
	{
		t = y - h;
		l = x - w;
	}

	// drag the widget (see dragable rules)
	if(dragx && (w > cw))
	{
		l += self->drag_dx;

		if(l > cl)
		{
			self->drag_dx -= l - cl;
			l = cl;
		}
		else if((l + w) < (cl + cw))
		{
			self->drag_dx += (cl + cw) - (l + w);
			l = cl + cw - w;
		}
		dragx = 0;
	}

	if(dragy && (h > ch))
	{
		t += self->drag_dy;

		if(t > ct)
		{
			self->drag_dy -= t - ct;
			t = ct;
		}
		else if((t + h) < (ct + ch))
		{
			self->drag_dy += (ct + ch) - (t + h);
			t = ct + ch - h;
		}
		dragy = 0;
	}

	// set the layout
	float h_bo = 0.0f;
	float v_bo = 0.0f;
	a3d_screen_layoutBorder(self->screen,
	                        self->style_border,
	                        &h_bo, &v_bo);
	self->rect_border.t = t;
	self->rect_border.l = l;
	self->rect_draw.t   = t + v_bo;
	self->rect_draw.l   = l + h_bo;

	// allow the widget to layout it's children
	a3d_widget_layout_fn layout_fn = self->layout_fn;
	if(layout_fn)
	{
		(*layout_fn)(self, dragx, dragy);
	}

	// initialize rounded rectangle
	float b = self->rect_border.t + self->rect_border.h;
	float r = self->rect_border.l + self->rect_border.w;
	float radius = (h_bo == v_bo) ? h_bo : 0.0f;
	int steps    = A3D_WIDGET_BEZEL;
	int size_rect = 4*steps*2;   // corners*steps*xy
	GLfloat vtx_rect[size_rect];
	a3d_widget_makeRoundRect(vtx_rect, steps,
	                         t + v_bo, l + h_bo,
	                         b - v_bo, r - v_bo,
	                         radius);
	glBindBuffer(GL_ARRAY_BUFFER, self->id_vtx_rect);
	glBufferData(GL_ARRAY_BUFFER, size_rect*sizeof(GLfloat),
	             vtx_rect, GL_STATIC_DRAW);

	a3d_rect4f_t rect_border_clip;
	if(a3d_rect4f_intersect(&self->rect_border,
	                        &self->rect_clip,
	                        &rect_border_clip))
	{
		if(self->scroll_bar)
		{
			float h_bo = 0.0f;
			float v_bo = 0.0f;
			a3d_screen_layoutBorder(self->screen,
			                        A3D_WIDGET_BORDER_MEDIUM,
			                        &h_bo, &v_bo);

			float w  = h_bo;
			float t  = rect_border_clip.t;
			float l  = rect_border_clip.l + rect_border_clip.w - w;
			float h  = rect_border_clip.h;
			float b  = t + h;
			float r  = l + w;
			int   sz = 16;   // 4*xyuv
			GLfloat xyuv[] =
			{
				l, t, 0.0f, 0.0f,   // top-left
				l, b, 0.0f, 1.0f,   // bottom-left
				r, t, 1.0f, 0.0f,   // top-right
				r, b, 1.0f, 1.0f,   // bottom-right
			};
			glBindBuffer(GL_ARRAY_BUFFER, self->scroll_id_vtx_rect);
			glBufferData(GL_ARRAY_BUFFER, sz*sizeof(GLfloat),
			             xyuv, GL_STATIC_DRAW);
		}
	}

	// initialize rounded line
	float lw = a3d_screen_layoutLine(self->screen, self->style_line);
	int size_line = 2*4*steps*2 + 2*2;   // edges*corners*steps*xy + edges*xy
	GLfloat vtx_line[size_line];
	a3d_widget_makeRoundLines(vtx_line, steps,
	                         t + v_bo, l + h_bo,
	                         b - v_bo, r - v_bo,
	                         radius, lw);
	glBindBuffer(GL_ARRAY_BUFFER, self->id_vtx_line);
	glBufferData(GL_ARRAY_BUFFER, size_line*sizeof(GLfloat),
	             vtx_line, GL_STATIC_DRAW);
}