diff options
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/color.c | 6 | ||||
-rw-r--r-- | src/ui/color.h | 40 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 102 | ||||
-rw-r--r-- | src/ui/inputwidget.c | 4 | ||||
-rw-r--r-- | src/ui/inputwidget.h | 26 | ||||
-rw-r--r-- | src/ui/labelwidget.c | 2 | ||||
-rw-r--r-- | src/ui/text.c | 4 | ||||
-rw-r--r-- | src/ui/widget.c | 1 |
8 files changed, 104 insertions, 81 deletions
diff --git a/src/ui/color.c b/src/ui/color.c index a6ba18e4..6c51bc06 100644 --- a/src/ui/color.c +++ b/src/ui/color.c | |||
@@ -468,12 +468,12 @@ const char *escape_Color(int color) { | |||
468 | return esc[color]; | 468 | return esc[color]; |
469 | } | 469 | } |
470 | /* TODO: Conflict with format strings! "%" (37) may be used as the color value. */ | 470 | /* TODO: Conflict with format strings! "%" (37) may be used as the color value. */ |
471 | /* Double-\r is used for range extension. */ | 471 | /* Double-\v is used for range extension. */ |
472 | if (color + asciiBase_ColorEscape > 127) { | 472 | if (color + asciiBase_ColorEscape > 127) { |
473 | iAssert(color - asciiExtended_ColorEscape + asciiBase_ColorEscape <= 127); | 473 | iAssert(color - asciiExtended_ColorEscape + asciiBase_ColorEscape <= 127); |
474 | return format_CStr("\r\r%c", color - asciiExtended_ColorEscape + asciiBase_ColorEscape); | 474 | return format_CStr("\v\v%c", color - asciiExtended_ColorEscape + asciiBase_ColorEscape); |
475 | } | 475 | } |
476 | return format_CStr("\r%c", color + asciiBase_ColorEscape); | 476 | return format_CStr("\v%c", color + asciiBase_ColorEscape); |
477 | } | 477 | } |
478 | 478 | ||
479 | iHSLColor setSat_HSLColor(iHSLColor d, float sat) { | 479 | iHSLColor setSat_HSLColor(iHSLColor d, float sat) { |
diff --git a/src/ui/color.h b/src/ui/color.h index d2fa3c00..aafc1794 100644 --- a/src/ui/color.h +++ b/src/ui/color.h | |||
@@ -187,26 +187,26 @@ iLocalDef iBool isRegularText_ColorId(enum iColorId d) { | |||
187 | #define asciiBase_ColorEscape 33 | 187 | #define asciiBase_ColorEscape 33 |
188 | #define asciiExtended_ColorEscape (128 - asciiBase_ColorEscape) | 188 | #define asciiExtended_ColorEscape (128 - asciiBase_ColorEscape) |
189 | 189 | ||
190 | #define restore_ColorEscape "\r\x24" /* ASCII Cancel */ | 190 | #define restore_ColorEscape "\v\x24" /* ASCII Cancel */ |
191 | #define black_ColorEscape "\r!" | 191 | #define black_ColorEscape "\v!" |
192 | #define gray25_ColorEscape "\r\"" | 192 | #define gray25_ColorEscape "\v\"" |
193 | #define gray50_ColorEscape "\r#" | 193 | #define gray50_ColorEscape "\v#" |
194 | #define gray75_ColorEscape "\r$" | 194 | #define gray75_ColorEscape "\v$" |
195 | #define white_ColorEscape "\r%" | 195 | #define white_ColorEscape "\v%" |
196 | #define brown_ColorEscape "\r&" | 196 | #define brown_ColorEscape "\v&" |
197 | #define orange_ColorEscape "\r'" | 197 | #define orange_ColorEscape "\v'" |
198 | #define teal_ColorEscape "\r(" | 198 | #define teal_ColorEscape "\v(" |
199 | #define cyan_ColorEscape "\r)" | 199 | #define cyan_ColorEscape "\v)" |
200 | #define yellow_ColorEscape "\r*" | 200 | #define yellow_ColorEscape "\v*" |
201 | #define red_ColorEscape "\r+" | 201 | #define red_ColorEscape "\v+" |
202 | #define magenta_ColorEscape "\r," | 202 | #define magenta_ColorEscape "\v," |
203 | #define blue_ColorEscape "\r-" | 203 | #define blue_ColorEscape "\v-" |
204 | #define green_ColorEscape "\r." | 204 | #define green_ColorEscape "\v." |
205 | #define uiText_ColorEscape "\r4" | 205 | #define uiText_ColorEscape "\v4" |
206 | #define uiTextAction_ColorEscape "\r<" | 206 | #define uiTextAction_ColorEscape "\v<" |
207 | #define uiTextCaution_ColorEscape "\r=" | 207 | #define uiTextCaution_ColorEscape "\v=" |
208 | #define uiTextStrong_ColorEscape "\r:" | 208 | #define uiTextStrong_ColorEscape "\v:" |
209 | #define uiHeading_ColorEscape "\rR" | 209 | #define uiHeading_ColorEscape "\vR" |
210 | 210 | ||
211 | iDeclareType(Color) | 211 | iDeclareType(Color) |
212 | iDeclareType(HSLColor) | 212 | iDeclareType(HSLColor) |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 6184a75a..29e264e8 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -1016,9 +1016,7 @@ static void showOrHidePinningIndicator_DocumentWidget_(iDocumentWidget *d) { | |||
1016 | isPinned_DocumentWidget_(d)); | 1016 | isPinned_DocumentWidget_(d)); |
1017 | } | 1017 | } |
1018 | 1018 | ||
1019 | void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) { | 1019 | static void documentWasChanged_DocumentWidget_(iDocumentWidget *d) { |
1020 | setUrl_GmDocument(d->doc, d->mod.url); | ||
1021 | setSource_GmDocument(d->doc, source, documentWidth_DocumentWidget_(d)); | ||
1022 | documentRunsInvalidated_DocumentWidget_(d); | 1020 | documentRunsInvalidated_DocumentWidget_(d); |
1023 | updateWindowTitle_DocumentWidget_(d); | 1021 | updateWindowTitle_DocumentWidget_(d); |
1024 | updateVisible_DocumentWidget_(d); | 1022 | updateVisible_DocumentWidget_(d); |
@@ -1034,7 +1032,23 @@ void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) { | |||
1034 | d->flags |= otherRootByDefault_DocumentWidgetFlag; | 1032 | d->flags |= otherRootByDefault_DocumentWidgetFlag; |
1035 | } | 1033 | } |
1036 | } | 1034 | } |
1037 | showOrHidePinningIndicator_DocumentWidget_(d); | 1035 | showOrHidePinningIndicator_DocumentWidget_(d); |
1036 | } | ||
1037 | |||
1038 | void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) { | ||
1039 | setUrl_GmDocument(d->doc, d->mod.url); | ||
1040 | setSource_GmDocument(d->doc, | ||
1041 | source, | ||
1042 | documentWidth_DocumentWidget_(d), | ||
1043 | isFinished_GmRequest(d->request) ? final_GmDocumentUpdate | ||
1044 | : partial_GmDocumentUpdate); | ||
1045 | documentWasChanged_DocumentWidget_(d); | ||
1046 | } | ||
1047 | |||
1048 | static void replaceDocument_DocumentWidget_(iDocumentWidget *d, iGmDocument *newDoc) { | ||
1049 | iRelease(d->doc); | ||
1050 | d->doc = ref_Object(newDoc); | ||
1051 | documentWasChanged_DocumentWidget_(d); | ||
1038 | } | 1052 | } |
1039 | 1053 | ||
1040 | static void updateTheme_DocumentWidget_(iDocumentWidget *d) { | 1054 | static void updateTheme_DocumentWidget_(iDocumentWidget *d) { |
@@ -1144,15 +1158,15 @@ static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode | |||
1144 | 2); | 1158 | 2); |
1145 | } | 1159 | } |
1146 | setBanner_GmDocument(d->doc, useBanner ? bannerType_DocumentWidget_(d) : none_GmDocumentBanner); | 1160 | setBanner_GmDocument(d->doc, useBanner ? bannerType_DocumentWidget_(d) : none_GmDocumentBanner); |
1147 | setFormat_GmDocument(d->doc, gemini_GmDocumentFormat); | 1161 | setFormat_GmDocument(d->doc, gemini_SourceFormat); |
1148 | translate_Lang(src); | 1162 | translate_Lang(src); |
1163 | d->state = ready_RequestState; | ||
1149 | setSource_DocumentWidget(d, src); | 1164 | setSource_DocumentWidget(d, src); |
1150 | updateTheme_DocumentWidget_(d); | 1165 | updateTheme_DocumentWidget_(d); |
1151 | reset_SmoothScroll(&d->scrollY); | 1166 | reset_SmoothScroll(&d->scrollY); |
1152 | init_Anim(&d->sideOpacity, 0); | 1167 | init_Anim(&d->sideOpacity, 0); |
1153 | init_Anim(&d->altTextOpacity, 0); | 1168 | init_Anim(&d->altTextOpacity, 0); |
1154 | resetWideRuns_DocumentWidget_(d); | 1169 | resetWideRuns_DocumentWidget_(d); |
1155 | d->state = ready_RequestState; | ||
1156 | } | 1170 | } |
1157 | 1171 | ||
1158 | static void updateFetchProgress_DocumentWidget_(iDocumentWidget *d) { | 1172 | static void updateFetchProgress_DocumentWidget_(iDocumentWidget *d) { |
@@ -1264,9 +1278,9 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d, iBool | |||
1264 | 2); | 1278 | 2); |
1265 | } | 1279 | } |
1266 | if (preloadCoverImage_Gempub(d->sourceGempub, d->doc)) { | 1280 | if (preloadCoverImage_Gempub(d->sourceGempub, d->doc)) { |
1267 | redoLayout_GmDocument(d->doc); | 1281 | redoLayout_GmDocument(d->doc); |
1268 | updateVisible_DocumentWidget_(d); | 1282 | updateVisible_DocumentWidget_(d); |
1269 | invalidate_DocumentWidget_(d); | 1283 | invalidate_DocumentWidget_(d); |
1270 | } | 1284 | } |
1271 | } | 1285 | } |
1272 | else if (equal_String(d->mod.url, indexPageUrl_Gempub(d->sourceGempub))) { | 1286 | else if (equal_String(d->mod.url, indexPageUrl_Gempub(d->sourceGempub))) { |
@@ -1348,7 +1362,9 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d, iBool | |||
1348 | } | 1362 | } |
1349 | } | 1363 | } |
1350 | 1364 | ||
1351 | static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse *response, | 1365 | static void updateDocument_DocumentWidget_(iDocumentWidget *d, |
1366 | const iGmResponse *response, | ||
1367 | iGmDocument *cachedDoc, | ||
1352 | const iBool isInitialUpdate) { | 1368 | const iBool isInitialUpdate) { |
1353 | if (d->state == ready_RequestState) { | 1369 | if (d->state == ready_RequestState) { |
1354 | return; | 1370 | return; |
@@ -1371,7 +1387,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse | |||
1371 | if (isSuccess_GmStatusCode(statusCode)) { | 1387 | if (isSuccess_GmStatusCode(statusCode)) { |
1372 | /* Check the MIME type. */ | 1388 | /* Check the MIME type. */ |
1373 | iRangecc charset = range_CStr("utf-8"); | 1389 | iRangecc charset = range_CStr("utf-8"); |
1374 | enum iGmDocumentFormat docFormat = undefined_GmDocumentFormat; | 1390 | enum iSourceFormat docFormat = undefined_SourceFormat; |
1375 | const iString *mimeStr = collect_String(lower_String(&response->meta)); /* for convenience */ | 1391 | const iString *mimeStr = collect_String(lower_String(&response->meta)); /* for convenience */ |
1376 | set_String(&d->sourceMime, mimeStr); | 1392 | set_String(&d->sourceMime, mimeStr); |
1377 | iRangecc mime = range_String(mimeStr); | 1393 | iRangecc mime = range_String(mimeStr); |
@@ -1380,20 +1396,20 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse | |||
1380 | iRangecc param = seg; | 1396 | iRangecc param = seg; |
1381 | trim_Rangecc(¶m); | 1397 | trim_Rangecc(¶m); |
1382 | if (equal_Rangecc(param, "text/gemini")) { | 1398 | if (equal_Rangecc(param, "text/gemini")) { |
1383 | docFormat = gemini_GmDocumentFormat; | 1399 | docFormat = gemini_SourceFormat; |
1384 | setRange_String(&d->sourceMime, param); | 1400 | setRange_String(&d->sourceMime, param); |
1385 | } | 1401 | } |
1386 | else if (startsWith_Rangecc(param, "text/") || | 1402 | else if (startsWith_Rangecc(param, "text/") || |
1387 | equal_Rangecc(param, "application/json") || | 1403 | equal_Rangecc(param, "application/json") || |
1388 | equal_Rangecc(param, "application/x-pem-file") || | 1404 | equal_Rangecc(param, "application/x-pem-file") || |
1389 | equal_Rangecc(param, "application/pem-certificate-chain")) { | 1405 | equal_Rangecc(param, "application/pem-certificate-chain")) { |
1390 | docFormat = plainText_GmDocumentFormat; | 1406 | docFormat = plainText_SourceFormat; |
1391 | setRange_String(&d->sourceMime, param); | 1407 | setRange_String(&d->sourceMime, param); |
1392 | } | 1408 | } |
1393 | else if (equal_Rangecc(param, "application/zip") || | 1409 | else if (equal_Rangecc(param, "application/zip") || |
1394 | (startsWith_Rangecc(param, "application/") && | 1410 | (startsWith_Rangecc(param, "application/") && |
1395 | endsWithCase_Rangecc(param, "+zip"))) { | 1411 | endsWithCase_Rangecc(param, "+zip"))) { |
1396 | docFormat = gemini_GmDocumentFormat; | 1412 | docFormat = gemini_SourceFormat; |
1397 | setRange_String(&d->sourceMime, param); | 1413 | setRange_String(&d->sourceMime, param); |
1398 | iString *key = collectNew_String(); | 1414 | iString *key = collectNew_String(); |
1399 | toString_Sym(SDLK_s, KMOD_PRIMARY, key); | 1415 | toString_Sym(SDLK_s, KMOD_PRIMARY, key); |
@@ -1420,9 +1436,10 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse | |||
1420 | startsWith_Rangecc(param, "audio/")) { | 1436 | startsWith_Rangecc(param, "audio/")) { |
1421 | const iBool isAudio = startsWith_Rangecc(param, "audio/"); | 1437 | const iBool isAudio = startsWith_Rangecc(param, "audio/"); |
1422 | /* Make a simple document with an image or audio player. */ | 1438 | /* Make a simple document with an image or audio player. */ |
1423 | docFormat = gemini_GmDocumentFormat; | 1439 | docFormat = gemini_SourceFormat; |
1424 | setRange_String(&d->sourceMime, param); | 1440 | setRange_String(&d->sourceMime, param); |
1425 | const iGmLinkId imgLinkId = 1; /* there's only the one link */ | 1441 | const iGmLinkId imgLinkId = 1; /* there's only the one link */ |
1442 | /* TODO: Do the image loading in `postProcessRequestContent_DocumentWidget_()` */ | ||
1426 | if ((isAudio && isInitialUpdate) || (!isAudio && isRequestFinished)) { | 1443 | if ((isAudio && isInitialUpdate) || (!isAudio && isRequestFinished)) { |
1427 | const char *linkTitle = | 1444 | const char *linkTitle = |
1428 | startsWith_String(mimeStr, "image/") ? "Image" : "Audio"; | 1445 | startsWith_String(mimeStr, "image/") ? "Image" : "Audio"; |
@@ -1464,7 +1481,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse | |||
1464 | } | 1481 | } |
1465 | } | 1482 | } |
1466 | } | 1483 | } |
1467 | if (docFormat == undefined_GmDocumentFormat) { | 1484 | if (docFormat == undefined_SourceFormat) { |
1468 | showErrorPage_DocumentWidget_(d, unsupportedMimeType_GmStatusCode, &response->meta); | 1485 | showErrorPage_DocumentWidget_(d, unsupportedMimeType_GmStatusCode, &response->meta); |
1469 | deinit_String(&str); | 1486 | deinit_String(&str); |
1470 | return; | 1487 | return; |
@@ -1476,7 +1493,10 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse | |||
1476 | collect_String(decode_Block(&str.chars, cstr_Rangecc(charset)))); | 1493 | collect_String(decode_Block(&str.chars, cstr_Rangecc(charset)))); |
1477 | } | 1494 | } |
1478 | } | 1495 | } |
1479 | if (setSource) { | 1496 | if (cachedDoc) { |
1497 | replaceDocument_DocumentWidget_(d, cachedDoc); | ||
1498 | } | ||
1499 | else if (setSource) { | ||
1480 | setSource_DocumentWidget(d, &str); | 1500 | setSource_DocumentWidget(d, &str); |
1481 | } | 1501 | } |
1482 | deinit_String(&str); | 1502 | deinit_String(&str); |
@@ -1556,14 +1576,15 @@ static void cacheDocumentGlyphs_DocumentWidget_(const iDocumentWidget *d) { | |||
1556 | } | 1576 | } |
1557 | 1577 | ||
1558 | static void updateFromCachedResponse_DocumentWidget_(iDocumentWidget *d, float normScrollY, | 1578 | static void updateFromCachedResponse_DocumentWidget_(iDocumentWidget *d, float normScrollY, |
1559 | const iGmResponse *resp) { | 1579 | const iGmResponse *resp, iGmDocument *cachedDoc) { |
1560 | setLinkNumberMode_DocumentWidget_(d, iFalse); | 1580 | setLinkNumberMode_DocumentWidget_(d, iFalse); |
1561 | clear_ObjectList(d->media); | 1581 | clear_ObjectList(d->media); |
1562 | delete_Gempub(d->sourceGempub); | 1582 | delete_Gempub(d->sourceGempub); |
1563 | d->sourceGempub = NULL; | 1583 | d->sourceGempub = NULL; |
1564 | reset_GmDocument(d->doc); | 1584 | iRelease(d->doc); |
1565 | destroy_Widget(d->footerButtons); | 1585 | destroy_Widget(d->footerButtons); |
1566 | d->footerButtons = NULL; | 1586 | d->footerButtons = NULL; |
1587 | d->doc = new_GmDocument(); | ||
1567 | resetWideRuns_DocumentWidget_(d); | 1588 | resetWideRuns_DocumentWidget_(d); |
1568 | d->state = fetching_RequestState; | 1589 | d->state = fetching_RequestState; |
1569 | /* Do the fetch. */ { | 1590 | /* Do the fetch. */ { |
@@ -1574,10 +1595,11 @@ static void updateFromCachedResponse_DocumentWidget_(iDocumentWidget *d, float n | |||
1574 | d->sourceStatus = success_GmStatusCode; | 1595 | d->sourceStatus = success_GmStatusCode; |
1575 | format_String(&d->sourceHeader, cstr_Lang("pageinfo.header.cached")); | 1596 | format_String(&d->sourceHeader, cstr_Lang("pageinfo.header.cached")); |
1576 | set_Block(&d->sourceContent, &resp->body); | 1597 | set_Block(&d->sourceContent, &resp->body); |
1577 | updateDocument_DocumentWidget_(d, resp, iTrue); | 1598 | updateDocument_DocumentWidget_(d, resp, cachedDoc, iTrue); |
1578 | postProcessRequestContent_DocumentWidget_(d, iTrue); | 1599 | setCachedDocument_History(d->mod.history, d->doc); |
1579 | } | 1600 | } |
1580 | d->state = ready_RequestState; | 1601 | d->state = ready_RequestState; |
1602 | postProcessRequestContent_DocumentWidget_(d, iTrue); | ||
1581 | init_Anim(&d->altTextOpacity, 0); | 1603 | init_Anim(&d->altTextOpacity, 0); |
1582 | reset_SmoothScroll(&d->scrollY); | 1604 | reset_SmoothScroll(&d->scrollY); |
1583 | init_Anim(&d->scrollY.pos, d->initNormScrollY * size_GmDocument(d->doc).y); | 1605 | init_Anim(&d->scrollY.pos, d->initNormScrollY * size_GmDocument(d->doc).y); |
@@ -1587,13 +1609,15 @@ static void updateFromCachedResponse_DocumentWidget_(iDocumentWidget *d, float n | |||
1587 | cacheDocumentGlyphs_DocumentWidget_(d); | 1609 | cacheDocumentGlyphs_DocumentWidget_(d); |
1588 | d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag | updateSideBuf_DrawBufsFlag; | 1610 | d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag | updateSideBuf_DrawBufsFlag; |
1589 | d->flags &= ~urlChanged_DocumentWidgetFlag; | 1611 | d->flags &= ~urlChanged_DocumentWidgetFlag; |
1590 | postCommandf_Root(as_Widget(d)->root, "document.changed doc:%p url:%s", d, cstr_String(d->mod.url)); | 1612 | postCommandf_Root( |
1613 | as_Widget(d)->root, "document.changed doc:%p url:%s", d, cstr_String(d->mod.url)); | ||
1591 | } | 1614 | } |
1592 | 1615 | ||
1593 | static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) { | 1616 | static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) { |
1594 | const iRecentUrl *recent = findUrl_History(d->mod.history, withSpacesEncoded_String(d->mod.url)); | 1617 | const iRecentUrl *recent = findUrl_History(d->mod.history, withSpacesEncoded_String(d->mod.url)); |
1595 | if (recent && recent->cachedResponse) { | 1618 | if (recent && recent->cachedResponse) { |
1596 | updateFromCachedResponse_DocumentWidget_(d, recent->normScrollY, recent->cachedResponse); | 1619 | updateFromCachedResponse_DocumentWidget_( |
1620 | d, recent->normScrollY, recent->cachedResponse, recent->cachedDoc); | ||
1597 | return iTrue; | 1621 | return iTrue; |
1598 | } | 1622 | } |
1599 | else if (!isEmpty_String(d->mod.url)) { | 1623 | else if (!isEmpty_String(d->mod.url)) { |
@@ -1843,13 +1867,14 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) { | |||
1843 | /* Keep scroll position when reloading the same page. */ | 1867 | /* Keep scroll position when reloading the same page. */ |
1844 | reset_SmoothScroll(&d->scrollY); | 1868 | reset_SmoothScroll(&d->scrollY); |
1845 | } | 1869 | } |
1846 | reset_GmDocument(d->doc); /* new content incoming */ | 1870 | iRelease(d->doc); /* new content incoming */ |
1871 | d->doc = new_GmDocument(); | ||
1847 | delete_Gempub(d->sourceGempub); | 1872 | delete_Gempub(d->sourceGempub); |
1848 | d->sourceGempub = NULL; | 1873 | d->sourceGempub = NULL; |
1849 | destroy_Widget(d->footerButtons); | 1874 | destroy_Widget(d->footerButtons); |
1850 | d->footerButtons = NULL; | 1875 | d->footerButtons = NULL; |
1851 | resetWideRuns_DocumentWidget_(d); | 1876 | resetWideRuns_DocumentWidget_(d); |
1852 | updateDocument_DocumentWidget_(d, resp, iTrue); | 1877 | updateDocument_DocumentWidget_(d, resp, NULL, iTrue); |
1853 | break; | 1878 | break; |
1854 | case categoryRedirect_GmStatusCode: | 1879 | case categoryRedirect_GmStatusCode: |
1855 | if (isEmpty_String(&resp->meta)) { | 1880 | if (isEmpty_String(&resp->meta)) { |
@@ -1900,7 +1925,7 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) { | |||
1900 | switch (category_GmStatusCode(statusCode)) { | 1925 | switch (category_GmStatusCode(statusCode)) { |
1901 | case categorySuccess_GmStatusCode: | 1926 | case categorySuccess_GmStatusCode: |
1902 | /* More content available. */ | 1927 | /* More content available. */ |
1903 | updateDocument_DocumentWidget_(d, resp, iFalse); | 1928 | updateDocument_DocumentWidget_(d, resp, NULL, iFalse); |
1904 | break; | 1929 | break; |
1905 | default: | 1930 | default: |
1906 | break; | 1931 | break; |
@@ -2085,16 +2110,16 @@ static const iString *saveToDownloads_(const iString *url, const iString *mime, | |||
2085 | exportDownloadedFile_iOS(savePath); | 2110 | exportDownloadedFile_iOS(savePath); |
2086 | #else | 2111 | #else |
2087 | if (showDialog) { | 2112 | if (showDialog) { |
2088 | const iMenuItem items[2] = { | 2113 | const iMenuItem items[2] = { |
2089 | { "${dlg.save.opendownload}", 0, 0, | 2114 | { "${dlg.save.opendownload}", 0, 0, |
2090 | format_CStr("!open url:%s", cstrCollect_String(makeFileUrl_String(savePath))) }, | 2115 | format_CStr("!open url:%s", cstrCollect_String(makeFileUrl_String(savePath))) }, |
2091 | { "${dlg.message.ok}", 0, 0, "message.ok" }, | 2116 | { "${dlg.message.ok}", 0, 0, "message.ok" }, |
2092 | }; | 2117 | }; |
2093 | makeMessage_Widget(uiHeading_ColorEscape "${heading.save}", | 2118 | makeMessage_Widget(uiHeading_ColorEscape "${heading.save}", |
2094 | format_CStr("%s\n${dlg.save.size} %.3f %s", | 2119 | format_CStr("%s\n${dlg.save.size} %.3f %s", |
2095 | cstr_String(path_File(f)), | 2120 | cstr_String(path_File(f)), |
2096 | isMega ? size / 1.0e6f : (size / 1.0e3f), | 2121 | isMega ? size / 1.0e6f : (size / 1.0e3f), |
2097 | isMega ? "${mb}" : "${kb}"), | 2122 | isMega ? "${mb}" : "${kb}"), |
2098 | items, | 2123 | items, |
2099 | iElemCount(items)); | 2124 | iElemCount(items)); |
2100 | } | 2125 | } |
@@ -2520,6 +2545,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
2520 | (startsWithCase_String(meta_GmRequest(d->request), "text/") || | 2545 | (startsWithCase_String(meta_GmRequest(d->request), "text/") || |
2521 | !cmp_String(&d->sourceMime, mimeType_Gempub))) { | 2546 | !cmp_String(&d->sourceMime, mimeType_Gempub))) { |
2522 | setCachedResponse_History(d->mod.history, lockResponse_GmRequest(d->request)); | 2547 | setCachedResponse_History(d->mod.history, lockResponse_GmRequest(d->request)); |
2548 | setCachedDocument_History(d->mod.history, d->doc); /* keeps a ref */ | ||
2523 | unlockResponse_GmRequest(d->request); | 2549 | unlockResponse_GmRequest(d->request); |
2524 | } | 2550 | } |
2525 | } | 2551 | } |
@@ -3875,9 +3901,9 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) { | |||
3875 | int bg = tmBackgroundOpenLink_ColorId; | 3901 | int bg = tmBackgroundOpenLink_ColorId; |
3876 | const int frame = tmFrameOpenLink_ColorId; | 3902 | const int frame = tmFrameOpenLink_ColorId; |
3877 | iRect wideRect = { init_I2(left_Rect(d->widgetBounds), visPos.y), | 3903 | iRect wideRect = { init_I2(left_Rect(d->widgetBounds), visPos.y), |
3878 | init_I2(width_Rect(d->widgetBounds) + | 3904 | init_I2(width_Rect(d->widgetBounds) + |
3879 | width_Widget(d->widget->scroll), | 3905 | width_Widget(d->widget->scroll), |
3880 | height_Rect(run->visBounds)) }; | 3906 | height_Rect(run->visBounds)) }; |
3881 | /* The first line is composed of two runs that may be drawn in either order, so | 3907 | /* The first line is composed of two runs that may be drawn in either order, so |
3882 | only draw half of the background. */ | 3908 | only draw half of the background. */ |
3883 | if (run->flags & decoration_GmRunFlag) { | 3909 | if (run->flags & decoration_GmRunFlag) { |
@@ -3940,7 +3966,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) { | |||
3940 | drawCentered_Text(defaultContentSmall_FontId, | 3966 | drawCentered_Text(defaultContentSmall_FontId, |
3941 | circleArea, | 3967 | circleArea, |
3942 | iTrue, | 3968 | iTrue, |
3943 | tmQuote_ColorId, | 3969 | tmQuote_ColorId, |
3944 | "%lc", | 3970 | "%lc", |
3945 | (int) ordChar); | 3971 | (int) ordChar); |
3946 | goto runDrawn; | 3972 | goto runDrawn; |
@@ -4624,8 +4650,8 @@ static void setUrl_DocumentWidget_(iDocumentWidget *d, const iString *url) { | |||
4624 | if (!equal_String(d->mod.url, url)) { | 4650 | if (!equal_String(d->mod.url, url)) { |
4625 | d->flags |= urlChanged_DocumentWidgetFlag; | 4651 | d->flags |= urlChanged_DocumentWidgetFlag; |
4626 | set_String(d->mod.url, url); | 4652 | set_String(d->mod.url, url); |
4627 | } | ||
4628 | } | 4653 | } |
4654 | } | ||
4629 | 4655 | ||
4630 | void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBool isFromCache) { | 4656 | void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBool isFromCache) { |
4631 | setLinkNumberMode_DocumentWidget_(d, iFalse); | 4657 | setLinkNumberMode_DocumentWidget_(d, iFalse); |
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index 32fb5ccb..cf128017 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -714,12 +714,12 @@ iLocalDef iBool isLastLine_InputWidget_(const iInputWidget *d, const iInputLine | |||
714 | } | 714 | } |
715 | 715 | ||
716 | static size_t indexForRelativeX_InputWidget_(const iInputWidget *d, int x, const iInputLine *line) { | 716 | static size_t indexForRelativeX_InputWidget_(const iInputWidget *d, int x, const iInputLine *line) { |
717 | size_t index = line->offset; | ||
717 | if (x <= 0) { | 718 | if (x <= 0) { |
718 | return line->offset; | 719 | return index; |
719 | } | 720 | } |
720 | const char *endPos; | 721 | const char *endPos; |
721 | tryAdvanceNoWrap_Text(d->font, range_String(&line->text), x, &endPos); | 722 | tryAdvanceNoWrap_Text(d->font, range_String(&line->text), x, &endPos); |
722 | size_t index = line->offset; | ||
723 | if (endPos == constEnd_String(&line->text)) { | 723 | if (endPos == constEnd_String(&line->text)) { |
724 | index += line->len; | 724 | index += line->len; |
725 | } | 725 | } |
diff --git a/src/ui/inputwidget.h b/src/ui/inputwidget.h index 5c39aae0..f8c5bf1e 100644 --- a/src/ui/inputwidget.h +++ b/src/ui/inputwidget.h | |||
@@ -41,20 +41,20 @@ struct Impl_InputWidgetContentPadding { | |||
41 | 41 | ||
42 | typedef void (*iInputWidgetValidatorFunc)(iInputWidget *, void *context); | 42 | typedef void (*iInputWidgetValidatorFunc)(iInputWidget *, void *context); |
43 | 43 | ||
44 | void setHint_InputWidget (iInputWidget *, const char *hintText); | 44 | void setHint_InputWidget (iInputWidget *, const char *hintText); |
45 | void setMode_InputWidget (iInputWidget *, enum iInputMode mode); | 45 | void setMode_InputWidget (iInputWidget *, enum iInputMode mode); |
46 | void setMaxLen_InputWidget (iInputWidget *, size_t maxLen); | 46 | void setMaxLen_InputWidget (iInputWidget *, size_t maxLen); |
47 | void setText_InputWidget (iInputWidget *, const iString *text); | 47 | void setText_InputWidget (iInputWidget *, const iString *text); |
48 | void setTextCStr_InputWidget (iInputWidget *, const char *cstr); | 48 | void setTextCStr_InputWidget (iInputWidget *, const char *cstr); |
49 | void setFont_InputWidget (iInputWidget *, int fontId); | 49 | void setFont_InputWidget (iInputWidget *, int fontId); |
50 | void setCursor_InputWidget (iInputWidget *, size_t pos); | 50 | void setCursor_InputWidget (iInputWidget *, size_t pos); |
51 | void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */ | 51 | void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */ |
52 | void setMaxLayoutLines_InputWidget (iInputWidget *, size_t maxLayoutLines); | 52 | void setMaxLayoutLines_InputWidget (iInputWidget *, size_t maxLayoutLines); |
53 | void setValidator_InputWidget (iInputWidget *, iInputWidgetValidatorFunc validator, void *context); | 53 | void setValidator_InputWidget (iInputWidget *, iInputWidgetValidatorFunc validator, void *context); |
54 | void setEnterKeyEnabled_InputWidget (iInputWidget *, iBool enterKeyEnabled); | 54 | void setEnterKeyEnabled_InputWidget (iInputWidget *, iBool enterKeyEnabled); |
55 | void begin_InputWidget (iInputWidget *); | 55 | void begin_InputWidget (iInputWidget *); |
56 | void end_InputWidget (iInputWidget *, iBool accept); | 56 | void end_InputWidget (iInputWidget *, iBool accept); |
57 | void selectAll_InputWidget (iInputWidget *); | 57 | void selectAll_InputWidget (iInputWidget *); |
58 | 58 | ||
59 | void setSelectAllOnFocus_InputWidget (iInputWidget *, iBool selectAllOnFocus); | 59 | void setSelectAllOnFocus_InputWidget (iInputWidget *, iBool selectAllOnFocus); |
60 | void setSensitiveContent_InputWidget (iInputWidget *, iBool isSensitive); | 60 | void setSensitiveContent_InputWidget (iInputWidget *, iBool isSensitive); |
@@ -62,15 +62,13 @@ void setUrlContent_InputWidget (iInputWidget *, iBool isUrl); | |||
62 | void setNotifyEdits_InputWidget (iInputWidget *, iBool notifyEdits); | 62 | void setNotifyEdits_InputWidget (iInputWidget *, iBool notifyEdits); |
63 | void setEatEscape_InputWidget (iInputWidget *, iBool eatEscape); | 63 | void setEatEscape_InputWidget (iInputWidget *, iBool eatEscape); |
64 | 64 | ||
65 | const iString * text_InputWidget (const iInputWidget *); | 65 | iInputWidgetContentPadding contentPadding_InputWidget (const iInputWidget *); |
66 | const iString * text_InputWidget (const iInputWidget *); | ||
66 | 67 | ||
67 | iLocalDef const char *cstrText_InputWidget(const iInputWidget *d) { | 68 | iLocalDef const char *cstrText_InputWidget(const iInputWidget *d) { |
68 | return cstr_String(text_InputWidget(d)); | 69 | return cstr_String(text_InputWidget(d)); |
69 | } | 70 | } |
70 | 71 | ||
71 | iInputWidgetContentPadding | ||
72 | contentPadding_InputWidget (const iInputWidget *); | ||
73 | |||
74 | iLocalDef iInputWidget *newHint_InputWidget(size_t maxLen, const char *hint) { | 72 | iLocalDef iInputWidget *newHint_InputWidget(size_t maxLen, const char *hint) { |
75 | iInputWidget *d = new_InputWidget(maxLen); | 73 | iInputWidget *d = new_InputWidget(maxLen); |
76 | setHint_InputWidget(d, hint); | 74 | setHint_InputWidget(d, hint); |
diff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c index 95f281be..ed023961 100644 --- a/src/ui/labelwidget.c +++ b/src/ui/labelwidget.c | |||
@@ -206,7 +206,7 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
206 | } | 206 | } |
207 | } | 207 | } |
208 | int colorEscape = none_ColorId; | 208 | int colorEscape = none_ColorId; |
209 | if (startsWith_String(&d->label, "\r")) { | 209 | if (startsWith_String(&d->label, "\v")) { |
210 | colorEscape = cstr_String(&d->label)[1] - asciiBase_ColorEscape; /* TODO: can be two bytes long */ | 210 | colorEscape = cstr_String(&d->label)[1] - asciiBase_ColorEscape; /* TODO: can be two bytes long */ |
211 | } | 211 | } |
212 | if (isHover_LabelWidget_(d)) { | 212 | if (isHover_LabelWidget_(d)) { |
diff --git a/src/ui/text.c b/src/ui/text.c index 55fd4254..ffe08fca 100644 --- a/src/ui/text.c +++ b/src/ui/text.c | |||
@@ -1010,10 +1010,10 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1010 | prevCh = 0; | 1010 | prevCh = 0; |
1011 | continue; | 1011 | continue; |
1012 | } | 1012 | } |
1013 | if (ch == '\r') { /* color change */ | 1013 | if (ch == '\v') { /* color change */ |
1014 | iChar esc = nextChar_(&chPos, args->text.end); | 1014 | iChar esc = nextChar_(&chPos, args->text.end); |
1015 | int colorNum = args->color; | 1015 | int colorNum = args->color; |
1016 | if (esc == '\r') { /* Extended range. */ | 1016 | if (esc == '\v') { /* Extended range. */ |
1017 | esc = nextChar_(&chPos, args->text.end) + asciiExtended_ColorEscape; | 1017 | esc = nextChar_(&chPos, args->text.end) + asciiExtended_ColorEscape; |
1018 | colorNum = esc - asciiBase_ColorEscape; | 1018 | colorNum = esc - asciiBase_ColorEscape; |
1019 | } | 1019 | } |
diff --git a/src/ui/widget.c b/src/ui/widget.c index 543b8bc9..4eac7ecf 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -321,7 +321,6 @@ static iBool setWidth_Widget_(iWidget *d, int width) { | |||
321 | d->rect.size.x = width; | 321 | d->rect.size.x = width; |
322 | TRACE(d, "width has changed to %d", width); | 322 | TRACE(d, "width has changed to %d", width); |
323 | if (class_Widget(d)->sizeChanged) { | 323 | if (class_Widget(d)->sizeChanged) { |
324 | const int oldHeight = d->rect.size.y; | ||
325 | class_Widget(d)->sizeChanged(d); | 324 | class_Widget(d)->sizeChanged(d); |
326 | } | 325 | } |
327 | return iTrue; | 326 | return iTrue; |