Skip to content

Commit

Permalink
Improve some widgets to add icon
Browse files Browse the repository at this point in the history
- Add BARS_LIST_ICONS to have a left icon
- Add nbgl_layoutAddChoiceButtonsIcon allowing an icon on the "top" button
- Add nbgl_pageDrawInfoIcon, calling nbgl_layoutAddChoiceButtonsIcon
- Add nbgl_useCaseHomeExtIcon to have an icon on the actionButton
  • Loading branch information
cedelavergne-ledger committed Feb 13, 2024
1 parent 158f76d commit 4f2ce89
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 31 deletions.
3 changes: 3 additions & 0 deletions lib_nbgl/include/nbgl_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,9 @@ int nbgl_layoutAddText(nbgl_layout_t *layout, const char *text, const char *subT
int nbgl_layoutAddRadioChoice(nbgl_layout_t *layout, const nbgl_layoutRadioChoice_t *choices);
int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info);
int nbgl_layoutAddChoiceButtons(nbgl_layout_t *layout, const nbgl_layoutChoiceButtons_t *info);
int nbgl_layoutAddChoiceButtonsIcon(nbgl_layout_t *layout,
const nbgl_layoutChoiceButtons_t *info,
const nbgl_icon_details_t *icon);
int nbgl_layoutAddTagValueList(nbgl_layout_t *layout, const nbgl_layoutTagValueList_t *list);
int nbgl_layoutAddLargeCaseText(nbgl_layout_t *layout, const char *text);
int nbgl_layoutAddSeparationLine(nbgl_layout_t *layout);
Expand Down
19 changes: 18 additions & 1 deletion lib_nbgl/include/nbgl_page.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ typedef enum {
SWITCHES_LIST, ///< list of switches with descriptions
INFOS_LIST, ///< list of infos with titles
CHOICES_LIST, ///< list of choices through radio buttons
BARS_LIST ///< list of touchable bars (with > on the right to go to sub-pages)
BARS_LIST, ///< list of touchable bars (with > on the right to go to sub-pages)
BARS_LIST_ICONS ///< list of touchable bars (with > on the right and icon on the left)
} nbgl_pageContentType_t;

/**
Expand Down Expand Up @@ -143,6 +144,17 @@ typedef struct nbgl_pageBarsList_s {
tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played when a bar is touched
} nbgl_pageBarsList_t;

/**
* @brief This structure contains data to build a @ref BARS_LIST page content
*/
typedef struct nbgl_pageBarsListIcons_s {
const char *const *barTexts; ///< array of texts for each bar (nbBars items, in black/bold)
const nbgl_icon_details_t *const *barIcons; ///< a buffer containing the 1BPP icons
const uint8_t *tokens; ///< array of tokens, one for each bar (nbBars items)
uint8_t nbBars; ///< number of elements in barTexts and tokens array
tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played when a bar is touched
} nbgl_pageBarsListIcons_t;

/**
* @brief This structure contains data to build a page in multi-pages mode (@ref
* nbgl_pageDrawGenericContent)
Expand All @@ -165,6 +177,7 @@ typedef struct nbgl_pageContent_s {
nbgl_pageInfoList_t infosList; ///< @ref INFOS_LIST type
nbgl_layoutRadioChoice_t choicesList; ///< @ref CHOICES_LIST type
nbgl_pageBarsList_t barsList; ///< @ref BARS_LIST type
nbgl_pageBarsListIcons_t barsListIcons; ///< @ref BARS_LIST type with icons
};
} nbgl_pageContent_t;

Expand Down Expand Up @@ -301,6 +314,10 @@ nbgl_page_t *nbgl_pageDrawSpinner(nbgl_layoutTouchCallback_t onActionCallback, c
nbgl_page_t *nbgl_pageDrawInfo(nbgl_layoutTouchCallback_t onActionCallback,
const nbgl_screenTickerConfiguration_t *ticker,
const nbgl_pageInfoDescription_t *info);
nbgl_page_t *nbgl_pageDrawInfoIcon(nbgl_layoutTouchCallback_t onActionCallback,
const nbgl_screenTickerConfiguration_t *ticker,
const nbgl_pageInfoDescription_t *info,
const nbgl_icon_details_t *topIcon);
nbgl_page_t *nbgl_pageDrawConfirmation(nbgl_layoutTouchCallback_t onActionCallback,
const nbgl_pageConfirmationDescription_t *info);
nbgl_page_t *nbgl_pageDrawGenericContentExt(nbgl_layoutTouchCallback_t onActionCallback,
Expand Down
9 changes: 9 additions & 0 deletions lib_nbgl/include/nbgl_use_case.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,15 @@ void nbgl_useCaseHomeExt(const char *appName,
nbgl_callback_t actionCallback,
nbgl_callback_t topRightCallback,
nbgl_callback_t quitCallback);
void nbgl_useCaseHomeExtIcon(const char *appName,
const nbgl_icon_details_t *appIcon,
const char *tagline,
bool withSettings,
const char *actionButtonText,
nbgl_callback_t actionCallback,
nbgl_callback_t topRightCallback,
nbgl_callback_t quitCallback,
const nbgl_icon_details_t *icon);
void nbgl_useCasePlugInHome(const char *plugInName,
const char *appName,
const nbgl_icon_details_t *appIcon,
Expand Down
98 changes: 81 additions & 17 deletions lib_nbgl/src/nbgl_layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -1031,19 +1031,29 @@ int nbgl_layoutAddTouchableBar(nbgl_layout_t *layout, const nbgl_layoutBar_t *ba
container->nbChildren++;
}
if (barLayout->subText != NULL) {
textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);

textArea->textColor = BLACK;
textArea->text = PIC(barLayout->subText);
textArea->textAlignment = MID_LEFT;
textArea->fontId = SMALL_REGULAR_FONT;
textArea->style = NO_STYLE;
textArea->wrapping = true;
textArea->obj.alignment = BOTTOM_LEFT;
textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
textArea->textColor = BLACK;
textArea->text = PIC(barLayout->subText);
textArea->textAlignment = MID_LEFT;
textArea->fontId = SMALL_REGULAR_FONT;
textArea->style = NO_STYLE;
textArea->wrapping = true;
textArea->obj.alignment = BOTTOM_LEFT;
textArea->obj.alignmentMarginY = BORDER_MARGIN;
textArea->obj.area.width = container->obj.area.width;
textArea->obj.area.height = nbgl_getTextHeightInWidth(
textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
if ((barLayout->iconLeft != NULL) && (barLayout->centered != true)) {
textArea->obj.alignmentMarginX = 12;
}
if (barLayout->iconLeft != NULL) {
textArea->obj.area.width -= imageLeft->buffer->width + 12;
textArea->obj.alignTo = (nbgl_obj_t *) imageLeft;
textArea->obj.alignment = MID_RIGHT;
}
if (barLayout->iconRight != NULL) {
textArea->obj.area.width -= ((nbgl_icon_details_t *) PIC(barLayout->iconRight))->width;
}
container->children[container->nbChildren] = (nbgl_obj_t *) textArea;
container->nbChildren++;
container->obj.area.height += textArea->obj.area.height + 16;
Expand Down Expand Up @@ -1834,13 +1844,17 @@ int nbgl_layoutAddCenteredInfo(nbgl_layout_t *layout, const nbgl_layoutCenteredI
*
* @param layout the current layout
* @param info structure giving the description of buttons (texts, icons, layout)
* @param icon icon blow QR code, above line(s)
* @return >= 0 if OK
*/
int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info)
int nbgl_layoutAddQRCodeIcon(nbgl_layout_t *layout,
const nbgl_layoutQRCode_t *info,
const nbgl_icon_details_t *icon)
{
nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout;
nbgl_container_t *container;
nbgl_text_area_t *textArea = NULL;
nbgl_image_t *image = NULL;
nbgl_qrcode_t *qrcode;
uint16_t fullHeight = 0;

Expand All @@ -1851,8 +1865,8 @@ int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info)

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

// get container children (max 2 (QRCode + text1/text2))
container->children = nbgl_containerPoolGet(2, layoutInt->layer);
// get container children (max 4: QRCode + icon + text1 + text2)
container->children = nbgl_containerPoolGet(4, layoutInt->layer);
container->nbChildren = 0;

qrcode = (nbgl_qrcode_t *) nbgl_objPoolGet(QR_CODE, layoutInt->layer);
Expand All @@ -1878,6 +1892,19 @@ int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info)
container->children[container->nbChildren] = (nbgl_obj_t *) qrcode;
container->nbChildren++;

if (icon != NULL) {
image = (nbgl_image_t *) nbgl_objPoolGet(IMAGE, layoutInt->layer);
image->foregroundColor = BLACK;
image->buffer = PIC(icon);
image->obj.area.bpp = NBGL_BPP_1;
image->obj.alignment = BOTTOM_MIDDLE;
image->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1];
image->obj.alignmentMarginY = 16;

fullHeight += image->buffer->height;
container->children[container->nbChildren] = (nbgl_obj_t *) image;
container->nbChildren++;
}
if (info->text1 != NULL) {
textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
textArea->textColor = BLACK;
Expand All @@ -1890,14 +1917,18 @@ int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info)
textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
textArea->obj.alignment = BOTTOM_MIDDLE;
textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1];
textArea->obj.alignmentMarginY = 40;

if (icon == NULL) {
textArea->obj.alignmentMarginY = 40;
}
else {
textArea->obj.alignmentMarginY = 12;
}
fullHeight += textArea->obj.area.height;

container->children[container->nbChildren] = (nbgl_obj_t *) textArea;
container->nbChildren++;
}
else if (info->text2 != NULL) {
if (info->text2 != NULL) {
textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
textArea->textColor = DARK_GRAY;
textArea->text = PIC(info->text2);
Expand All @@ -1909,7 +1940,12 @@ int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info)
textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
textArea->obj.alignment = BOTTOM_MIDDLE;
textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1];
textArea->obj.alignmentMarginY = 40;
if (icon == NULL) {
textArea->obj.alignmentMarginY = 40;
}
else {
textArea->obj.alignmentMarginY = 12;
}

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

Expand All @@ -1936,6 +1972,18 @@ int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info)

return 0;
}
/**
* @brief Creates an area on the center of the main panel, with a QRCode,
* a possible text in black (bold) under it, and a possible text in black under it
*
* @param layout the current layout
* @param info structure giving the description of buttons (texts, icons, layout)
* @return >= 0 if OK
*/
int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info)
{
return nbgl_layoutAddQRCodeIcon(layout, info, NULL);
}
#endif // NBGL_QRCODE

#ifdef HAVE_SE_TOUCH
Expand All @@ -1944,9 +1992,12 @@ int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info)
*
* @param layout the current layout
* @param info structure giving the description of buttons (texts, icons, layout)
* @param icon a buffer containing the 1BPP icon for top button
* @return >= 0 if OK
*/
int nbgl_layoutAddChoiceButtons(nbgl_layout_t *layout, const nbgl_layoutChoiceButtons_t *info)
int nbgl_layoutAddChoiceButtonsIcon(nbgl_layout_t *layout,
const nbgl_layoutChoiceButtons_t *info,
const nbgl_icon_details_t *icon)
{
layoutObj_t *obj;
nbgl_button_t *topButton, *bottomButton;
Expand Down Expand Up @@ -2007,6 +2058,7 @@ int nbgl_layoutAddChoiceButtons(nbgl_layout_t *layout, const nbgl_layoutChoiceBu
else {
topButton->obj.alignmentMarginY = 4; // 4 pixels from bottom button
}
topButton->icon = icon;
topButton->innerColor = BLACK;
topButton->borderColor = BLACK;
topButton->foregroundColor = WHITE;
Expand All @@ -2023,6 +2075,18 @@ int nbgl_layoutAddChoiceButtons(nbgl_layout_t *layout, const nbgl_layoutChoiceBu
return 0;
}

/**
* @brief Creates two buttons to make a choice. Both buttons are mandatory
*
* @param layout the current layout
* @param info structure giving the description of buttons (texts, icons, layout)
* @return >= 0 if OK
*/
int nbgl_layoutAddChoiceButtons(nbgl_layout_t *layout, const nbgl_layoutChoiceButtons_t *info)
{
return nbgl_layoutAddChoiceButtonsIcon(layout, info, NULL);
}

/**
* @brief Creates a list of [tag,value] pairs
*
Expand Down
42 changes: 38 additions & 4 deletions lib_nbgl/src/nbgl_page.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,22 @@ static void addContent(nbgl_pageContent_t *content, nbgl_layout_t *layout)
}
break;
}
case BARS_LIST_ICONS: {
uint8_t i;
for (i = 0; i < content->barsListIcons.nbBars; i++) {
nbgl_layoutBar_t bar;
bar.text = content->barsListIcons.barTexts[i];
bar.subText = NULL;
bar.iconRight = &C_Next32px;
bar.iconLeft = content->barsListIcons.barIcons[i];
bar.token = content->barsListIcons.tokens[i];
bar.centered = false;
bar.tuneId = content->barsListIcons.tuneId;
nbgl_layoutAddTouchableBar(layout, &bar);
nbgl_layoutAddSeparationLine(layout);
}
break;
}
}
}

Expand Down Expand Up @@ -262,11 +278,13 @@ nbgl_page_t *nbgl_pageDrawSpinner(nbgl_layoutTouchCallback_t onActionCallback, c
* @param onActionCallback common callback for all actions on this page
* @param ticker ticker configuration, set to NULL to disable it
* @param info structure describing the centered info and other controls of this page
* @param topIcon a buffer containing the 1BPP icon for top button
* @return the page context (or NULL if error)
*/
nbgl_page_t *nbgl_pageDrawInfo(nbgl_layoutTouchCallback_t onActionCallback,
const nbgl_screenTickerConfiguration_t *ticker,
const nbgl_pageInfoDescription_t *info)
nbgl_page_t *nbgl_pageDrawInfoIcon(nbgl_layoutTouchCallback_t onActionCallback,
const nbgl_screenTickerConfiguration_t *ticker,
const nbgl_pageInfoDescription_t *info,
const nbgl_icon_details_t *topIcon)
{
nbgl_layoutDescription_t layoutDescription;
nbgl_layout_t *layout;
Expand Down Expand Up @@ -330,7 +348,7 @@ nbgl_page_t *nbgl_pageDrawInfo(nbgl_layoutTouchCallback_t onActionC
.token = info->bottomButtonsToken,
.style = BOTH_ROUNDED_STYLE,
.tuneId = info->tuneId};
nbgl_layoutAddChoiceButtons(layout, &buttonsInfo);
nbgl_layoutAddChoiceButtonsIcon(layout, &buttonsInfo, topIcon);
}
else {
nbgl_layoutButton_t buttonInfo = {.fittingContent = false,
Expand Down Expand Up @@ -365,6 +383,22 @@ nbgl_page_t *nbgl_pageDrawInfo(nbgl_layoutTouchCallback_t onActionC
return (nbgl_page_t *) layout;
}

/**
* @brief draw a page with a centered info (icon and/or texts) with a touchable footer,
* in a potential "tapable" area, with an optional top-right button, with an optional bottom button
*
* @param onActionCallback common callback for all actions on this page
* @param ticker ticker configuration, set to NULL to disable it
* @param info structure describing the centered info and other controls of this page
* @return the page context (or NULL if error)
*/
nbgl_page_t *nbgl_pageDrawInfo(nbgl_layoutTouchCallback_t onActionCallback,
const nbgl_screenTickerConfiguration_t *ticker,
const nbgl_pageInfoDescription_t *info)
{
return (nbgl_page_t *) nbgl_pageDrawInfoIcon(onActionCallback, ticker, info, NULL);
}

/**
* @brief draw a confirmation page, with a centered info (icon and/or text), a button to confirm and
* a footer to cancel
Expand Down
Loading

0 comments on commit 4f2ce89

Please sign in to comment.