Example #1
0
static void a3d_hline_size(a3d_widget_t* widget,
                           float* w, float* h)
{
	assert(widget);
	assert(w);
	assert(h);

	a3d_hline_t* self = (a3d_hline_t*) widget;
	a3d_font_t*  font = a3d_screen_font(widget->screen,
	                                    A3D_SCREEN_FONT_REGULAR);
	float       size = a3d_screen_layoutText(widget->screen, self->style);
	if(self->wrapx == A3D_HLINE_WRAP_STRETCH)
	{
		float aspect  = a3d_font_aspectRatioAvg(font);
		int   max_len = self->max_len;
		*w = size*aspect*max_len;
	}
	else if(self->wrapx == A3D_HLINE_WRAP_STRETCH_PARENT)
	{
		// ignore
	}
	else
	{
		float width  = (float) a3d_hline_width(self);
		float height = (float) a3d_hline_height(self);
		*w = size*(width/height);
	}
	*h = size;
}
Example #2
0
static void a3d_textbox_reflow(a3d_widget_t* widget,
                               float w, float h)
{
	assert(widget);
	LOGD("debug w=%f, h=%f", w, h);

	a3d_textbox_t* self = (a3d_textbox_t*) widget;

	// reflow text when changes occur
	if((self->dirty  == 0) &&
	   (self->last_w == w) &&
	   (self->last_h == h))
	{
		return;
	}
	self->dirty  = 0;
	self->last_w = w;
	self->last_h = h;

	// determine maxi
	a3d_font_t* font   = a3d_screen_font(widget->screen);
	float       aspect = a3d_font_aspectRatio(font);
	float       size   = a3d_screen_layoutText(widget->screen,
	                                           self->style_text);
	int         maxi   = (int) (w/(aspect*size)) - 1;

	// maxi does not include null character
	// but max_len does
	// limit to max_len
	if((maxi >= self->max_len) ||
	   (maxi == 0))
	{
		maxi = self->max_len - 1;
	}

	// clear the text
	a3d_listbox_t*  listbox = (a3d_listbox_t*) self;
	a3d_listitem_t* iter    = a3d_list_head(listbox->list);
	while(iter)
	{
		a3d_text_t* text;
		text = (a3d_text_t*) a3d_list_remove(listbox->list, &iter);
		a3d_text_delete(&text);
	}

	// initialize parser
	char tok[256];
	char dst[256];
	int  srci = 0;
	int  toki = 0;
	int  dsti = 0;
	int  type = A3D_TOKEN_END;

	// reflow the string(s)
	iter = a3d_list_head(self->strings);
	while(iter)
	{
		const char* src = (const char*) a3d_list_peekitem(iter);

		srci = 0;
		type = getToken(src, tok, &srci, &toki);
		while(type != A3D_TOKEN_END)
		{
			if(type == A3D_TOKEN_BREAK)
			{
				if(dsti > 0)
				{
					a3d_textbox_printText(self, dst);
					a3d_textbox_printText(self, "");
				}
				else
				{
					a3d_textbox_printText(self, "");
				}
				dsti = 0;
				break;
			}

			if(dsti == 0)
			{
				strncpy(dst, tok, 256);
				dst[255] = '\0';
				dsti = toki;
			}
			else
			{
				if(dsti + toki + 1 <= maxi)
				{
					strcat(dst, " ");
					strcat(dst, tok);
					dst[255] = '\0';
					dsti += toki + 1;
				}
				else
				{
					a3d_textbox_printText(self, dst);

					strncpy(dst, tok, 256);
					dst[255] = '\0';
					dsti = toki;
				}
			}

			type = getToken(src, tok, &srci, &toki);
		}

		iter = a3d_list_next(iter);
	}

	if(dsti > 0)
	{
		a3d_textbox_printText(self, dst);
	}
}
Example #3
0
void a3d_widget_layoutSize(a3d_widget_t* self,
                           float* w, float* h)
{
	assert(self);
	assert(w);
	assert(h);
	LOGD("debug w=%f, h=%f", *w, *h);

	float sw;
	float sh;
	a3d_screen_sizef(self->screen, &sw, &sh);

	a3d_font_t* font = a3d_screen_font(self->screen,
	                                   A3D_SCREEN_FONT_REGULAR);
	float ar = a3d_font_aspectRatioAvg(font);
	float th = 0.0f;
	if((self->wrapy >= A3D_WIDGET_WRAP_STRETCH_TEXT_SMALL) &&
	   (self->wrapy <= A3D_WIDGET_WRAP_STRETCH_TEXT_LARGE))
	{
		int style = self->wrapy - A3D_WIDGET_WRAP_STRETCH_TEXT_SMALL;
		th = a3d_screen_layoutText(self->screen, style);
	}
	float tw = ar*th;

	// screen/text/parent square
	float ssq = (sw > sh) ? sh : sw;
	float tsq = th;   // always use the height for square
	float psq = (*w > *h) ? *h : *w;
	int   sq  = (self->stretch_mode == A3D_WIDGET_STRETCH_SQUARE);

	// initialize size
	float h_bo = 0.0f;
	float v_bo = 0.0f;
	a3d_screen_layoutBorder(self->screen,
	                        self->style_border,
	                        &h_bo, &v_bo);
	if(self->wrapx == A3D_WIDGET_WRAP_SHRINK)
	{
		self->rect_draw.w   = *w - 2.0f*h_bo;
		self->rect_border.w = *w;
	}
	else
	{
		float rw = 0.0f;
		if(self->wrapx == A3D_WIDGET_WRAP_STRETCH_SCREEN)
		{
			rw = sq ? ssq : sw;
			rw *= self->stretch_factor;
			self->rect_draw.w   = rw - 2.0f*h_bo;
			self->rect_border.w = rw;
		}
		else if((self->wrapx >= A3D_WIDGET_WRAP_STRETCH_TEXT_SMALL) &&
		        (self->wrapx <= A3D_WIDGET_WRAP_STRETCH_TEXT_LARGE))
		{
			rw = sq ? tsq : tw;
			rw *= self->stretch_factor;
			self->rect_draw.w   = rw;
			self->rect_border.w = rw + 2.0f*h_bo;
		}
		else
		{
			rw = sq ? psq : *w;
			rw *= self->stretch_factor;
			self->rect_draw.w   = rw - 2.0f*h_bo;
			self->rect_border.w = rw;
		}
	}

	// intersect draw with border interior
	if(self->rect_draw.w < 0.0f)
	{
		self->rect_draw.w = 0.0f;
	}

	if(self->wrapy == A3D_WIDGET_WRAP_SHRINK)
	{
		self->rect_draw.h   = *h - 2.0f*v_bo;
		self->rect_border.h = *h;
	}
	else
	{
		float rh = 0.0f;
		if(self->wrapy == A3D_WIDGET_WRAP_STRETCH_SCREEN)
		{
			rh = sq ? ssq : sh;
			rh *= self->stretch_factor;
			self->rect_draw.h   = rh - 2.0f*v_bo;
			self->rect_border.h = rh;
		}
		else if((self->wrapy >= A3D_WIDGET_WRAP_STRETCH_TEXT_SMALL) &&
		        (self->wrapy <= A3D_WIDGET_WRAP_STRETCH_TEXT_LARGE))
		{
			rh = sq ? tsq : th;
			rh *= self->stretch_factor;
			self->rect_draw.h   = rh;
			self->rect_border.h = rh + 2.0f*v_bo;
		}
		else
		{
			rh = sq ? psq : *h;
			rh *= self->stretch_factor;
			self->rect_draw.h   = rh - 2.0f*v_bo;
			self->rect_border.h = rh;
		}
	}

	// intersect draw with border interior
	if(self->rect_draw.h < 0.0f)
	{
		self->rect_draw.h = 0.0f;
	}

	// reflow dynamically sized widgets (e.g. textbox)
	// this makes the most sense for stretched widgets
	float draw_w = self->rect_draw.w;
	float draw_h = self->rect_draw.h;
	a3d_widget_reflow_fn reflow_fn = self->reflow_fn;
	if(reflow_fn)
	{
		(*reflow_fn)(self, draw_w, draw_h);
	}

	// compute draw size for shrink wrapped widgets and
	// recursively compute size of any children
	// the draw size of the widget also becomes the border
	// size of any children
	a3d_widget_size_fn size_fn = self->size_fn;
	if(size_fn)
	{
		(*size_fn)(self, &draw_w, &draw_h);
	}

	// wrap width
	if(self->wrapx == A3D_WIDGET_WRAP_SHRINK)
	{
		self->rect_draw.w   = draw_w;
		self->rect_border.w = draw_w + 2.0f*h_bo;
	}

	// wrap height
	if(self->wrapy == A3D_WIDGET_WRAP_SHRINK)
	{
		self->rect_draw.h   = draw_h;
		self->rect_border.h = draw_h + 2.0f*v_bo;
	}

	*w = self->rect_border.w;
	*h = self->rect_border.h;
}