Skip to content

Commit

Permalink
Add a new "content center" layout object to better match Figma
Browse files Browse the repository at this point in the history
  • Loading branch information
nroggeman-ledger committed Jun 21, 2024
1 parent be09f0e commit 3d0d0a7
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 3 deletions.
20 changes: 20 additions & 0 deletions lib_nbgl/include/nbgl_content.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,26 @@ typedef struct {
#endif // HAVE_SE_TOUCH
} nbgl_contentCenteredInfo_t;

/**
* @brief This structure contains info to build a centered (vertically and horizontally) area, with
* many fields (if NULL, not used):
* - an icon (with a possible hug)
* - a title in black large case
* - a sub-title in black small bold case
* - a description in black small regular case
* - a sub-text in dark gray regular small case
* - a padding on the bottom
*/
typedef struct {
const nbgl_icon_details_t *icon; ///< the icon (can be null)
const char *title; ///< title in black large (can be null)
const char *smallTitle; ///< sub-title in black small bold case (can be null)
const char *description; ///< description in black small regular case (can be null)
const char *subText; ///< sub-text in dark gray regular small case
uint16_t iconHug; // vertical margin to apply on top and bottom of the icon
bool padding; // if true, apply a padding of 40px at the bottom
} nbgl_contentCenter_t;

/**
* @brief This structure contains data to build a centered info + long press button content
*/
Expand Down
1 change: 1 addition & 0 deletions lib_nbgl/include/nbgl_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ typedef struct {
**********************/
nbgl_layout_t *nbgl_layoutGet(const nbgl_layoutDescription_t *description);
int nbgl_layoutAddCenteredInfo(nbgl_layout_t *layout, const nbgl_layoutCenteredInfo_t *info);
int nbgl_layoutAddContentCenter(nbgl_layout_t *layout, const nbgl_contentCenter_t *info);
int nbgl_layoutAddProgressBar(nbgl_layout_t *layout, const nbgl_layoutProgressBar_t *barLayout);

#ifdef HAVE_SE_TOUCH
Expand Down
178 changes: 178 additions & 0 deletions lib_nbgl/src/nbgl_layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,184 @@ int nbgl_layoutAddCenteredInfo(nbgl_layout_t *layout, const nbgl_layoutCenteredI
return 0;
}

/**
* @brief Creates an area on the center of the main panel, with a possible icon,
* and possible texts under it
*
* @param layout the current layout
* @param info structure giving the description of the Content Center
* @return the size of the area if OK
*/
int nbgl_layoutAddContentCenter(nbgl_layout_t *layout, const nbgl_contentCenter_t *info)
{
nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout;
nbgl_container_t *container;
nbgl_text_area_t *textArea = NULL;
nbgl_image_t *image = NULL;
uint16_t fullHeight = 0;

LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddContentCenter():\n");
if (layout == NULL) {
return -1;
}

container = (nbgl_container_t *) nbgl_objPoolGet(CONTAINER, layoutInt->layer);

// get container children
container->nbChildren = 0;
container->children = nbgl_containerPoolGet(5, layoutInt->layer);

// add icon if present
if (info->icon != NULL) {
image = (nbgl_image_t *) nbgl_objPoolGet(IMAGE, layoutInt->layer);
image->foregroundColor = BLACK;
image->buffer = PIC(info->icon);
image->obj.area.bpp = NBGL_BPP_1;
image->obj.alignment = TOP_MIDDLE;
image->obj.alignmentMarginY = info->iconHug;

fullHeight += image->buffer->height + info->iconHug;
container->children[container->nbChildren] = (nbgl_obj_t *) image;
container->nbChildren++;
}
// add title if present
if (info->title != NULL) {
textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
textArea->textColor = BLACK;
textArea->text = PIC(info->title);
textArea->textAlignment = CENTER;
textArea->fontId = LARGE_MEDIUM_FONT;
textArea->wrapping = true;
textArea->obj.area.width = AVAILABLE_WIDTH;
textArea->obj.area.height = nbgl_getTextHeightInWidth(
textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);

// if not the first child, put on bottom of the previous, with a margin
if (container->nbChildren > 0) {
textArea->obj.alignment = BOTTOM_MIDDLE;
textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1];
textArea->obj.alignmentMarginY = BOTTOM_BORDER_MARGIN + info->iconHug;
}
else {
textArea->obj.alignment = TOP_MIDDLE;
}

fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;

container->children[container->nbChildren] = (nbgl_obj_t *) textArea;
container->nbChildren++;
}
// add small title if present
if (info->smallTitle != NULL) {
textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
textArea->textColor = BLACK;
textArea->text = PIC(info->smallTitle);
textArea->textAlignment = CENTER;
textArea->fontId = SMALL_BOLD_FONT;
textArea->wrapping = true;
textArea->obj.area.width = AVAILABLE_WIDTH;
textArea->obj.area.height = nbgl_getTextHeightInWidth(
textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);

// if not the first child, put on bottom of the previous, with a margin
if (container->nbChildren > 0) {
textArea->obj.alignment = BOTTOM_MIDDLE;
textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1];
textArea->obj.alignmentMarginY = BOTTOM_BORDER_MARGIN;
if (container->children[container->nbChildren - 1]->type == IMAGE) {
textArea->obj.alignmentMarginY = BOTTOM_BORDER_MARGIN + info->iconHug;
}
else {
textArea->obj.alignmentMarginY = 16;
}
}
else {
textArea->obj.alignment = TOP_MIDDLE;
}

fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;

container->children[container->nbChildren] = (nbgl_obj_t *) textArea;
container->nbChildren++;
}
// add description if present
if (info->description != NULL) {
textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
textArea->textColor = BLACK;
textArea->text = PIC(info->description);
textArea->textAlignment = CENTER;
textArea->fontId = SMALL_REGULAR_FONT;
textArea->wrapping = true;
textArea->obj.area.width = AVAILABLE_WIDTH;
textArea->obj.area.height = nbgl_getTextHeightInWidth(
textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);

// if not the first child, put on bottom of the previous, with a margin
if (container->nbChildren > 0) {
textArea->obj.alignment = BOTTOM_MIDDLE;
textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1];
if (container->children[container->nbChildren - 1]->type == TEXT_AREA) {
// if previous element is text, only space of 16 px
textArea->obj.alignmentMarginY = 16;
}
else {
textArea->obj.alignmentMarginY = BOTTOM_BORDER_MARGIN + info->iconHug;
}
}
else {
textArea->obj.alignment = TOP_MIDDLE;
}

fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;

container->children[container->nbChildren] = (nbgl_obj_t *) textArea;
container->nbChildren++;
}
// add sub-text if present
if (info->subText != NULL) {
textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
textArea->textColor = DARK_GRAY;
textArea->text = PIC(info->subText);
textArea->textAlignment = CENTER;
textArea->fontId = SMALL_REGULAR_FONT;
textArea->wrapping = true;
textArea->obj.area.width = AVAILABLE_WIDTH;
textArea->obj.area.height = nbgl_getTextHeightInWidth(
textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
// sub-text is included in a hug of 8px
textArea->obj.area.height += 2 * 8;
// if not the first child, put on bottom of the previous, with a margin
if (container->nbChildren > 0) {
textArea->obj.alignment = BOTTOM_MIDDLE;
textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1];
textArea->obj.alignmentMarginY = 16;
if (container->children[container->nbChildren - 1]->type == IMAGE) {
textArea->obj.alignmentMarginY += info->iconHug;
}
}
else {
textArea->obj.alignment = TOP_MIDDLE;
}

fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;

container->children[container->nbChildren] = (nbgl_obj_t *) textArea;
container->nbChildren++;
}
container->layout = VERTICAL;
container->obj.alignment = CENTER;
container->obj.area.width = AVAILABLE_WIDTH;
container->obj.area.height = fullHeight;
if (info->padding) {
container->obj.area.height += 40;
}

// set this new container as child of main container
layoutAddObject(layoutInt, (nbgl_obj_t *) container);

return fullHeight;
}

#ifdef NBGL_QRCODE
/**
* @brief Creates an area on the center of the main panel, with a QRCode,
Expand Down
7 changes: 4 additions & 3 deletions lib_nbgl/src/nbgl_use_case.c
Original file line number Diff line number Diff line change
Expand Up @@ -2625,9 +2625,10 @@ void nbgl_useCaseGenericReview(const nbgl_genericContents_t *contents,
memset(&genericContext, 0, sizeof(genericContext));

// memorize context
onQuit = rejectCallback;
navType = GENERIC_NAV;
pageTitle = NULL;
onQuit = rejectCallback;
navType = GENERIC_NAV;
pageTitle = NULL;
bundleNavContext.review.operationType = TYPE_OPERATION;

memcpy(&genericContext.genericContents, contents, sizeof(nbgl_genericContents_t));

Expand Down

0 comments on commit 3d0d0a7

Please sign in to comment.