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 22, 2024
1 parent 876b8a5 commit 610acb1
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 25 deletions.
20 changes: 19 additions & 1 deletion lib_nbgl/include/nbgl_content.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,19 @@ typedef struct {
#endif // HAVE_PIEZO_SOUND
} nbgl_contentBarsList_t;

/**
* @brief This structure contains data to build a @ref BARS_LIST_ICONS content
*/
typedef struct nbgl_contentBarsListIcons_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
#ifdef HAVE_PIEZO_SOUND
tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played when a bar is touched
#endif // HAVE_PIEZO_SOUND
} nbgl_contentBarsListIcons_t;

/**
* @brief The different types of predefined contents
*
Expand All @@ -255,11 +268,15 @@ 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_contentType_t;

/**
* @brief Union of the different type of contents
*
* @note This union is duplicated in nbgl_page.h: @ref nbgl_pageContent_t
*
*/
typedef union {
nbgl_contentCenteredInfo_t centeredInfo; ///< @ref CENTERED_INFO type
Expand All @@ -272,6 +289,7 @@ typedef union {
nbgl_contentInfoList_t infosList; ///< @ref INFOS_LIST type
nbgl_contentRadioChoice_t choicesList; ///< @ref CHOICES_LIST type
nbgl_contentBarsList_t barsList; ///< @ref BARS_LIST type
nbgl_contentBarsListIcons_t barsListIcons; ///< @ref BARS_LIST_ICONS type
} nbgl_content_u;

/**
Expand Down
6 changes: 6 additions & 0 deletions lib_nbgl/include/nbgl_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,13 @@ int nbgl_layoutAddSwitch(nbgl_layout_t *layout, const nbgl_layoutSwitch_t *switc
int nbgl_layoutAddText(nbgl_layout_t *layout, const char *text, const char *subText);
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_layoutAddQRCodeIcon(nbgl_layout_t *layout,
const nbgl_layoutQRCode_t *info,
const nbgl_icon_details_t *icon);
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
8 changes: 8 additions & 0 deletions lib_nbgl/include/nbgl_page.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ typedef nbgl_contentInfoLongPress_t nbgl_pageInfoLongPress_t;
/**
* @brief This structure contains data to build a page in multi-pages mode (@ref
* nbgl_pageDrawGenericContent)
*
* @note This union is duplicated in nbgl_content.h: @ref nbgl_content_u
*
*/
typedef struct nbgl_pageContent_s {
const char *title; ///< text for the title of the page (if NULL, no title)
Expand All @@ -67,6 +70,7 @@ typedef struct nbgl_pageContent_s {
nbgl_contentInfoList_t infosList; ///< @ref INFOS_LIST type
nbgl_contentRadioChoice_t choicesList; ///< @ref CHOICES_LIST type
nbgl_contentBarsList_t barsList; ///< @ref BARS_LIST type
nbgl_contentBarsListIcons_t barsListIcons; ///< @ref BARS_LIST_ICONS type
};
} nbgl_pageContent_t;

Expand Down Expand Up @@ -203,6 +207,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 @@ -142,6 +142,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
93 changes: 82 additions & 11 deletions lib_nbgl/src/nbgl_layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -1032,8 +1032,12 @@ int nbgl_layoutAddTouchableBar(nbgl_layout_t *layout, const nbgl_layoutBar_t *ba
}
if (barLayout->subText != NULL) {
textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);

textArea->textColor = BLACK;
if (barLayout->iconLeft != NULL) {
textArea->textColor = DARK_GRAY;
}
else {
textArea->textColor = BLACK;
}
textArea->text = PIC(barLayout->subText);
textArea->textAlignment = MID_LEFT;
textArea->fontId = SMALL_REGULAR_FONT;
Expand All @@ -1044,6 +1048,18 @@ int nbgl_layoutAddTouchableBar(nbgl_layout_t *layout, const nbgl_layoutBar_t *ba
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.alignmentMarginY += 12;
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 +1850,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,13 +1871,14 @@ 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);
// version is forced to V10 if url is longer than 62 characters
if (strlen(PIC(info->url)) > 62) {
if ((strlen(PIC(info->url)) > 62)
|| ((icon != NULL) && (info->text1 != NULL) && (info->text2 != NULL))) {
qrcode->version = QRCODE_V10;
}
else {
Expand All @@ -1878,6 +1899,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 +1924,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 +1947,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 +1979,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 +1999,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 +2065,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 +2082,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

0 comments on commit 610acb1

Please sign in to comment.