コード例 #1
0
int paintButtons(	const button_label_ext * const content,
			const int &count, 
			const int &x,	
			const int &y, 
			const int &footerwidth, 
			const int &footerheight,
			const int &maxwidth,
			bool show,
			int *wantedwidth,
			int *wantedheight)
{
	CFrameBuffer *frameBuffer = CFrameBuffer::getInstance();
	Font * font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_FOOT];
	int cnt = count;
	int x_footer = x;
	int y_footer = y;
	int w_footer = footerwidth;
	int h_footer = 0;
	
	int w_space 	= 10; //minimal space between buttons
	int h_space	= 4; //minimal space between caption and/or icon and border
	int x_icon 	= x_footer + w_space;
	int x_caption 	= 0;
	
	int x_button = x_icon;
	int h_button = 0;
	
	//calculate max of h + w
	//icon
	int h_max_icon = 0;
	int w_icons = 0;
	
	//text
	int w_text = 0;
	int h_max_text = font->getHeight();

	int count_icons = 0;
	int count_labels = 0;
	/* more than 16 buttons? noooooo*/
	int iconw[16];
	int iconh[16];
	int fwidth[16];
	const char *buttontext[16];

	/* sanity check... */
	if (count > 16 || count == 0)
	{
		fprintf(stderr, "paintButtons does only support max 16 buttons yet (%d)\n", count);
// 		print_stacktrace();
		return 0;
	}
	if (maxwidth < 200 && show)
	{
		fprintf(stderr, "paintButtons: maxwidth very small\n");
		fprintf(stderr, "  x: %d y: %d footw: %d count: %d maxw: %d footh: %d\n ",
				x, y, footerwidth, count, maxwidth, footerheight);
// 		print_stacktrace();
	}

	bool maximize = false;
	for (int i = 0; i < cnt; i++)
		maximize |= content[i].maximize;

	for (int i = 0; i < cnt; i++)
	{
		//icon
		int w = 0;
		int h = 0;
		frameBuffer->getIconSize(content[i].button, &w, &h);
		iconw[i] = w;
		iconh[i] = h;
		h_max_icon = std::max(h_max_icon, h);
		w_icons += w;
		if (w)
			count_icons++;

		if (content[i].text) {
			buttontext[i] = content[i].text;
			fwidth[i] = std::max(content[i].width, font->getRenderWidth(buttontext[i]));
			w_text += fwidth[i];
			count_labels++;
		} else if (content[i].locale) {
			buttontext[i] = g_Locale->getText(content[i].locale);
			fwidth[i] = std::max(content[i].width, font->getRenderWidth(buttontext[i]));
			w_text += fwidth[i];
			count_labels++;
		} else {
			buttontext[i] = "";
			fwidth[i] = 0;
		}
		if (maximize && i < cnt - 1)
			fwidth[i] += w, w_text += w;
	}

	//calculate button heigth
	h_button = std::max(h_max_icon, h_max_text); //calculate optimal button height
	
	//calculate footer heigth
	h_footer = footerheight == 0 ? (h_button + 2*h_space) : footerheight;

	if (!show) {
		if (wantedheight)
			*wantedheight = h_button + 2*h_space;
		if (wantedwidth)
			*wantedwidth = w_space * 2 + w_text + w_icons + (count_icons + count_labels - 1) * h_space;
		return h_footer;
	}

	//paint footer
	if (w_footer > 0)
		frameBuffer->paintBoxRel(x_footer, y_footer, w_footer, h_footer, COL_MENUFOOT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); //round

	
	//baseline
	int y_base = y_footer + h_footer/2;
	int spacing = maxwidth - w_space * 2 - w_text - w_icons - (count_icons + count_labels - 1) * h_space;
#if 0
	/* debug */
	fprintf(stderr, "PB: sp %d mw %d w_t %d w_i %d w_s %d c_i %d\n",
		spacing, maxwidth, w_text, w_icons, w_space, count_items);
#endif
	if (fwidth[cnt - 1] == 0) /* divisor needs to be labels+1 unless rightmost icon has a label */
		count_labels++;   /* side effect: we don't try to divide by 0 :-) */

	if (maximize) {
		while (spacing > 0) {
			for (int i = 0; i < cnt && spacing > 0; i++) {
				if (content[i].maximize) {
					fwidth[i]++;
					spacing--;
				}
			}
		}
	}

	if (spacing >= 0)
	{
		int tmp = count_labels ? count_labels : 1;//avoid division by zero
						/* add half of the inter-object space to the */
		spacing /= tmp;	 		/* left and right (this might break vertical */
		x_button += spacing / 2;	/* alignment, but nobody is using this (yet) */
	}					/* and I'm don't know how it should work.    */
	else
	{
		w_text = w_text ? w_text : 1;
		/* shorten captions relative to their length */
		for (int i = 0; i < cnt; i++)
			fwidth[i] = (fwidth[i] * (w_text + spacing)) / w_text; /* spacing is negative...*/
		spacing = 0;
	}

	for (int j = 0; j < cnt; j++)
	{
		const char * caption = NULL;
		//set caption... 
		caption = buttontext[j];

		const char * icon = content[j].button ? content[j].button : "";

		// calculate baseline startposition of icon and text in y
 		int y_caption = y_base + h_max_text/2+1;
		
		// paint icon and text
		frameBuffer->paintIcon(icon, x_button , y_base - iconh[j]/2);
		x_caption = x_button + iconw[j] + h_space;
		font->RenderString(x_caption, y_caption, fwidth[j], caption, COL_MENUFOOT_TEXT);
 		
 		/* 	set next startposition x, if text is length=0 then offset is =renderwidth of icon, 
  		* 	for generating buttons without captions, 
  		*/		
 		
		/* increase x position */
		x_button = x_caption;
		if (fwidth[j])
			x_button += fwidth[j] + spacing + h_space;
	}

	return h_footer;
}
コード例 #2
0
int paintButtons(       const int &x,
		const int &y,
		const int &footerwidth,
		const uint &count,
		const struct button_label * const content,
		const int &maxwidth,
		const int &footerheight,
		std::string /* just to make sure nobody uses anything below */,
		bool vertical_paint,
		const uint32_t fcolor,
		const char * alt_buttontext,
		const uint &buttontext_id,
		bool show,
		const std::vector<neutrino_locale_t>& /*all_buttontext_id*/)
{
	CFrameBuffer *frameBuffer = CFrameBuffer::getInstance();
	Font * font = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL];
	uint cnt = count;
	int x_footer = x;
	int y_footer = y;
	int w_footer = footerwidth;
	int h_footer = 0;

	int w_space     = 10; //minimal space between buttons
	int h_space     = 4; //minimal space between caption and/or icon and border
	int x_icon      = x_footer + w_space;
	int x_caption   = 0;

	int x_button = x_icon;
	int h_button = 0;

	//calculate max of h + w
	//icon
	int h_max_icon = 0;
	int w_icons = 0;

	//text
	int w_text = 0;
	int h_max_text = font->getHeight();
	int count_icons = 0;
	int count_labels = 0;
	/* more than 16 buttons? noooooo*/
	int iconw[16];
	int iconh[16];
	int fwidth[16];
	const char *buttontext[16];

	/* sanity check... */
	if (count > 16 || count == 0)
	{
		fprintf(stderr, "paintButtons does only support max 16 buttons yet (%d)\n", count);
		//print_stacktrace();
		return 0;
	}
	if (maxwidth < 200 && show)
	{
		fprintf(stderr, "paintButtons: maxwidth very small\n");
		fprintf(stderr, "  x: %d y: %d footw: %d count: %d maxw: %d footh: %d\n ",
				x, y, footerwidth, count, maxwidth, footerheight);
		//print_stacktrace();
	}

	uint i;
	for (i = 0; i < cnt; i++)
	{
		//icon
		int w = 0;
		int h = 0;
		frameBuffer->getIconSize(content[i].button, &w, &h);
		iconw[i] = w;
		iconh[i] = h;
		h_max_icon = std::max(h_max_icon, h);
		w_icons += w;
		if (w)
			count_icons++;

		if (content[i].locale) {
			buttontext[i] = g_Locale->getText(content[i].locale);
			//text width
			if (alt_buttontext != NULL && i == buttontext_id)
				fwidth[i] = font->getRenderWidth(alt_buttontext); //...with an alternate buttontext
			else
				fwidth[i] = font->getRenderWidth(buttontext[i]);
			w_text += fwidth[i];
			count_labels++;
		} else {
			buttontext[i] = "";
			fwidth[i] = 0;
		}
	}

	//calculate button heigth
	h_button = std::max(h_max_icon, h_max_text); //calculate optimal button height

	//calculate footer heigth
	h_footer = footerheight == 0 ? (h_button + 2*h_space) : footerheight;

	if (!show)
		return h_footer;

	//paint footer
	if (w_footer > 0)
		frameBuffer->paintBoxRel(x_footer, y_footer, w_footer, h_footer, COL_INFOBAR_SHADOW_PLUS_1, RADIUS_LARGE, CORNER_BOTTOM); //round


	//baseline
	int y_base = y_footer + h_footer/2;
	int spacing = maxwidth - w_space * 2 - w_text - w_icons - (count_icons + count_labels - 1) * h_space;
#if 0
	/* debug */
	fprintf(stderr, "PB: sp %d mw %d w_t %d w_i %d w_s %d c_i %d\n",
			spacing, maxwidth, w_text, w_icons, w_space, count_items);
#endif
	if (fwidth[cnt - 1] == 0) /* divisor needs to be labels+1 unless rightmost icon has a label */
		count_labels++;   /* side effect: we don't try to divide by 0 :-) */
	if (spacing >= 0)
	{                                /* add half of the inter-object space to the */
		spacing /= count_labels; /* left and right (this might break vertical */
		x_button += spacing / 2; /* alignment, but nobody is using this (yet) */
	}                                /* and I'm don't know how it should work.    */
	else
	{
		/* shorten captions relative to their length */
		int tmp = w_text ? w_text : 1;//avoid division by zero
		for (i = 0; i < cnt; i++)
			fwidth[i] = (fwidth[i] * (w_text + spacing)) / tmp; /* spacing is negative...*/
		spacing = 0;
	}

	for (uint j = 0; j < cnt; j++)
	{
		const char * caption = NULL;
		//set caption... 
		if (alt_buttontext != NULL && j == buttontext_id)
			caption = alt_buttontext; //...with an alternate buttontext
		else
			caption = buttontext[j];

		const char * icon = content[j].button ? content[j].button : "";

		// calculate baseline startposition of icon and text in y
		int y_caption = y_base + h_max_text/2+1;

		// paint icon and text
		frameBuffer->paintIcon(icon, x_button , y_base - iconh[j]/2);
		x_caption = x_button + iconw[j] + h_space;
		font->RenderString(x_caption, y_caption, fwidth[j], caption, fcolor);

		/*      set next startposition x, if text is length=0 then offset is =renderwidth of icon, 
		 *       for generating buttons without captions, 
		 */

		int lentext = strlen(caption);
		if (vertical_paint)
			// set x_icon for painting buttons with vertical arrangement 
		{
			if (lentext !=0)
			{
				x_button = x;
				y_base += h_footer;
			}
			else
			{
				x_button = x_caption;
			}
		}
		else
		{
			/* increase x position */
			x_button = x_caption;
			if (fwidth[j])
				x_button += fwidth[j] + spacing + h_space;
		}
	}

	return h_footer;
}