48
48
/* max number of char for reduced QR Code address */
49
49
#define QRCODE_REDUCED_ADDR_LEN 128
50
50
51
+ /* maximum number of pairs in a page of address confirm */
52
+ #define ADDR_VERIF_NB_PAIRS 3
53
+
51
54
// macros to ease access to shared contexts
52
55
#define keypadContext sharedContext.keypad
53
56
#define reviewWithWarnCtx sharedContext.reviewWithWarning
@@ -116,8 +119,9 @@ typedef struct DetailsContext_s {
116
119
} DetailsContext_t ;
117
120
118
121
typedef struct AddressConfirmationContext_s {
119
- nbgl_layoutTagValue_t tagValuePair ;
122
+ nbgl_layoutTagValue_t tagValuePairs [ ADDR_VERIF_NB_PAIRS ] ;
120
123
nbgl_layout_t * modalLayout ;
124
+ uint8_t nbPairs ;
121
125
} AddressConfirmationContext_t ;
122
126
123
127
#ifdef NBGL_KEYPAD
@@ -1420,7 +1424,7 @@ static void displayAddressQRCode(void)
1420
1424
.tapActionText = NULL };
1421
1425
nbgl_layoutHeader_t headerDesc = {
1422
1426
.type = HEADER_EMPTY , .separationLine = false, .emptySpace .height = SMALL_CENTERING_HEADER };
1423
- nbgl_layoutQRCode_t qrCode = {.url = addressConfirmationContext .tagValuePair .value ,
1427
+ nbgl_layoutQRCode_t qrCode = {.url = addressConfirmationContext .tagValuePairs [ 0 ] .value ,
1424
1428
.text1 = NULL ,
1425
1429
.centered = true,
1426
1430
.offsetY = 0 };
@@ -1429,16 +1433,18 @@ static void displayAddressQRCode(void)
1429
1433
// add empty header for better look
1430
1434
nbgl_layoutAddHeader (addressConfirmationContext .modalLayout , & headerDesc );
1431
1435
// compute nb lines to check whether it shall be shorten (max is 3 lines)
1432
- uint16_t nbLines = nbgl_getTextNbLinesInWidth (
1433
- SMALL_REGULAR_FONT , addressConfirmationContext .tagValuePair .value , AVAILABLE_WIDTH , false);
1436
+ uint16_t nbLines = nbgl_getTextNbLinesInWidth (SMALL_REGULAR_FONT ,
1437
+ addressConfirmationContext .tagValuePairs [0 ].value ,
1438
+ AVAILABLE_WIDTH ,
1439
+ false);
1434
1440
1435
1441
if (nbLines <= QRCODE_NB_MAX_LINES ) {
1436
- qrCode .text2 = addressConfirmationContext .tagValuePair .value ; // in gray
1442
+ qrCode .text2 = addressConfirmationContext .tagValuePairs [ 0 ] .value ; // in gray
1437
1443
}
1438
1444
else {
1439
1445
// only keep beginning and end of text, and add ... in the middle
1440
1446
nbgl_textReduceOnNbLines (SMALL_REGULAR_FONT ,
1441
- addressConfirmationContext .tagValuePair .value ,
1447
+ addressConfirmationContext .tagValuePairs [ 0 ] .value ,
1442
1448
AVAILABLE_WIDTH ,
1443
1449
QRCODE_NB_MAX_LINES ,
1444
1450
reducedAddress ,
@@ -1757,6 +1763,7 @@ static uint8_t getNbTagValuesInPage(uint8_t nbPairs,
1757
1763
uint8_t startIndex ,
1758
1764
bool isSkippable ,
1759
1765
bool hasConfirmationButton ,
1766
+ bool hasDetailsButton ,
1760
1767
bool * requireSpecificDisplay )
1761
1768
{
1762
1769
uint8_t nbPairsInPage = 0 ;
@@ -1844,6 +1851,13 @@ static uint8_t getNbTagValuesInPage(uint8_t nbPairs,
1844
1851
nbPairsInPage -- ;
1845
1852
}
1846
1853
}
1854
+ // do the same with just a details button
1855
+ else if (hasDetailsButton ) {
1856
+ maxUsableHeight -= (SMALL_BUTTON_RADIUS * 2 );
1857
+ if (currentHeight > maxUsableHeight ) {
1858
+ nbPairsInPage -- ;
1859
+ }
1860
+ }
1847
1861
return nbPairsInPage ;
1848
1862
}
1849
1863
@@ -1865,15 +1879,21 @@ static uint8_t getNbPagesForContent(const nbgl_content_t *content,
1865
1879
// if the current page is not the first one (or last), a navigation bar exists
1866
1880
bool hasNav = !isLast || (pageIdxStart > 0 ) || (elemIdx > 0 );
1867
1881
if (content -> type == TAG_VALUE_LIST ) {
1868
- nbElementsInPage = getNbTagValuesInPage (
1869
- nbElements , & content -> content .tagValueList , elemIdx , isSkippable , false, & flag );
1882
+ nbElementsInPage = getNbTagValuesInPage (nbElements ,
1883
+ & content -> content .tagValueList ,
1884
+ elemIdx ,
1885
+ isSkippable ,
1886
+ false,
1887
+ false,
1888
+ & flag );
1870
1889
}
1871
1890
else if (content -> type == TAG_VALUE_CONFIRM ) {
1872
1891
nbElementsInPage = getNbTagValuesInPage (nbElements ,
1873
1892
& content -> content .tagValueConfirm .tagValueList ,
1874
1893
elemIdx ,
1875
1894
isSkippable ,
1876
- true,
1895
+ isLast ,
1896
+ !isLast ,
1877
1897
& flag );
1878
1898
}
1879
1899
else if (content -> type == INFOS_LIST ) {
@@ -1934,18 +1954,37 @@ static void prepareAddressConfirmationPages(const char *ad
1934
1954
{
1935
1955
nbgl_contentTagValueConfirm_t * tagValueConfirm ;
1936
1956
1937
- addressConfirmationContext .tagValuePair .item = "Address" ;
1938
- addressConfirmationContext .tagValuePair .value = address ;
1957
+ addressConfirmationContext .tagValuePairs [0 ].item = "Address" ;
1958
+ addressConfirmationContext .tagValuePairs [0 ].value = address ;
1959
+ addressConfirmationContext .nbPairs = 1 ;
1939
1960
1940
1961
// First page
1941
1962
firstPageContent -> type = TAG_VALUE_CONFIRM ;
1942
1963
tagValueConfirm = & firstPageContent -> content .tagValueConfirm ;
1943
1964
1944
1965
#ifdef NBGL_QRCODE
1945
1966
tagValueConfirm -> detailsButtonIcon = & QRCODE_ICON ;
1946
- // only use "Show as QR" when it's not the last page
1947
- if (tagValueList != NULL ) {
1948
- tagValueConfirm -> detailsButtonText = "Show as QR" ;
1967
+ // only use "Show as QR" when address & pairs are not fitting in a single page
1968
+ if ((tagValueList != NULL ) && (tagValueList -> nbPairs < ADDR_VERIF_NB_PAIRS )) {
1969
+ nbgl_contentTagValueList_t tmpList ;
1970
+ bool flag ;
1971
+ // copy in intermediate structure
1972
+ for (uint8_t i = 0 ; i < tagValueList -> nbPairs ; i ++ ) {
1973
+ memcpy (& addressConfirmationContext .tagValuePairs [1 + i ],
1974
+ & tagValueList -> pairs [i ],
1975
+ sizeof (nbgl_contentTagValue_t ));
1976
+ addressConfirmationContext .nbPairs ++ ;
1977
+ }
1978
+ // check how many can fit in a page
1979
+ memcpy (& tmpList , tagValueList , sizeof (nbgl_contentTagValueList_t ));
1980
+ tmpList .nbPairs = addressConfirmationContext .nbPairs ;
1981
+ tmpList .pairs = addressConfirmationContext .tagValuePairs ;
1982
+ addressConfirmationContext .nbPairs = getNbTagValuesInPage (
1983
+ addressConfirmationContext .nbPairs , & tmpList , 0 , false, true, true, & flag );
1984
+ // if they don't all fit, keep only the address
1985
+ if (tmpList .nbPairs > addressConfirmationContext .nbPairs ) {
1986
+ addressConfirmationContext .nbPairs = 1 ;
1987
+ }
1949
1988
}
1950
1989
else {
1951
1990
tagValueConfirm -> detailsButtonText = NULL ;
@@ -1956,24 +1995,17 @@ static void prepareAddressConfirmationPages(const char *ad
1956
1995
tagValueConfirm -> detailsButtonIcon = NULL ;
1957
1996
#endif // NBGL_QRCODE
1958
1997
tagValueConfirm -> tuneId = TUNE_TAP_CASUAL ;
1959
- tagValueConfirm -> tagValueList .nbPairs = 1 ;
1960
- tagValueConfirm -> tagValueList .pairs = & addressConfirmationContext .tagValuePair ;
1998
+ tagValueConfirm -> tagValueList .nbPairs = addressConfirmationContext . nbPairs ;
1999
+ tagValueConfirm -> tagValueList .pairs = addressConfirmationContext .tagValuePairs ;
1961
2000
tagValueConfirm -> tagValueList .smallCaseForValue = false;
1962
2001
tagValueConfirm -> tagValueList .nbMaxLinesForValue = 0 ;
1963
2002
tagValueConfirm -> tagValueList .wrapping = false;
1964
2003
// if it's an extended address verif, it takes 2 pages, so display a "Tap to continue", and
1965
2004
// no confirmation button
1966
- if (tagValueList != NULL ) {
1967
- tagValueConfirm -> confirmationText = NULL ;
1968
- }
1969
- else {
1970
- // otherwise no tap to continue but a confirmation button
1971
- tagValueConfirm -> confirmationText = "Confirm" ;
1972
- tagValueConfirm -> confirmationToken = CONFIRM_TOKEN ;
1973
- }
1974
-
1975
- // Second page if any:
1976
- if (tagValueList != NULL ) {
2005
+ if ((tagValueList != NULL )
2006
+ && (tagValueList -> nbPairs > (addressConfirmationContext .nbPairs - 1 ))) {
2007
+ tagValueConfirm -> detailsButtonText = "Show as QR" ;
2008
+ tagValueConfirm -> confirmationText = NULL ;
1977
2009
// the second page is dedicated to the extended tag/value pairs
1978
2010
secondPageContent -> type = TAG_VALUE_CONFIRM ;
1979
2011
tagValueConfirm = & secondPageContent -> content .tagValueConfirm ;
@@ -1983,6 +2015,15 @@ static void prepareAddressConfirmationPages(const char *ad
1983
2015
tagValueConfirm -> detailsButtonIcon = NULL ;
1984
2016
tagValueConfirm -> tuneId = TUNE_TAP_CASUAL ;
1985
2017
memcpy (& tagValueConfirm -> tagValueList , tagValueList , sizeof (nbgl_contentTagValueList_t ));
2018
+ tagValueConfirm -> tagValueList .nbPairs
2019
+ = tagValueList -> nbPairs - (addressConfirmationContext .nbPairs - 1 );
2020
+ tagValueConfirm -> tagValueList .pairs
2021
+ = & tagValueList -> pairs [addressConfirmationContext .nbPairs - 1 ];
2022
+ }
2023
+ else {
2024
+ // otherwise no tap to continue but a confirmation button
2025
+ tagValueConfirm -> confirmationText = "Confirm" ;
2026
+ tagValueConfirm -> confirmationToken = CONFIRM_TOKEN ;
1986
2027
}
1987
2028
}
1988
2029
@@ -2710,7 +2751,7 @@ uint8_t nbgl_useCaseGetNbTagValuesInPage(uint8_t nbPai
2710
2751
bool * requireSpecificDisplay )
2711
2752
{
2712
2753
return getNbTagValuesInPage (
2713
- nbPairs , tagValueList , startIndex , false, false, requireSpecificDisplay );
2754
+ nbPairs , tagValueList , startIndex , false, false, false, requireSpecificDisplay );
2714
2755
}
2715
2756
2716
2757
/**
@@ -2733,7 +2774,7 @@ uint8_t nbgl_useCaseGetNbTagValuesInPageExt(uint8_t nb
2733
2774
bool * requireSpecificDisplay )
2734
2775
{
2735
2776
return getNbTagValuesInPage (
2736
- nbPairs , tagValueList , startIndex , isSkippable , false, requireSpecificDisplay );
2777
+ nbPairs , tagValueList , startIndex , isSkippable , false, false, requireSpecificDisplay );
2737
2778
}
2738
2779
2739
2780
/**
@@ -4072,7 +4113,6 @@ void nbgl_useCaseAddressReview(const char *address,
4072
4113
bundleNavContext .review .operationType = TYPE_OPERATION ;
4073
4114
4074
4115
genericContext .genericContents .contentsList = localContentsList ;
4075
- genericContext .genericContents .nbContents = (additionalTagValueList == NULL ) ? 2 : 3 ;
4076
4116
memset (localContentsList , 0 , 3 * sizeof (nbgl_content_t ));
4077
4117
4078
4118
// First a centered info
@@ -4086,6 +4126,8 @@ void nbgl_useCaseAddressReview(const char *address,
4086
4126
address , additionalTagValueList , & localContentsList [1 ], & localContentsList [2 ]);
4087
4127
4088
4128
// fill navigation structure, common to all pages
4129
+ genericContext .genericContents .nbContents
4130
+ = (localContentsList [2 ].type == TAG_VALUE_CONFIRM ) ? 3 : 2 ;
4089
4131
uint8_t nbPages = getNbPagesForGenericContents (& genericContext .genericContents , 0 , false);
4090
4132
4091
4133
prepareNavInfo (true, nbPages , "Cancel" );
0 commit comments