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; }
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; }