summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/defs.h2
-rw-r--r--src/gempub.c37
-rw-r--r--src/gempub.h4
-rw-r--r--src/gmdocument.c3
-rw-r--r--src/ui/documentwidget.c80
5 files changed, 122 insertions, 4 deletions
diff --git a/src/defs.h b/src/defs.h
index d592abb2..d16c56f5 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -36,6 +36,8 @@ enum iFileVersion {
36 36
37/* Icons */ 37/* Icons */
38 38
39#define rightArrowhead_Icon "\u27a4"
40#define leftArrowhead_Icon "\u27a4"
39#define warning_Icon "\u26a0" 41#define warning_Icon "\u26a0"
40#define openLock_Icon "\U0001f513" 42#define openLock_Icon "\U0001f513"
41#define closedLock_Icon "\U0001f512" 43#define closedLock_Icon "\U0001f512"
diff --git a/src/gempub.c b/src/gempub.c
index aa03d835..f3021add 100644
--- a/src/gempub.c
+++ b/src/gempub.c
@@ -213,6 +213,10 @@ iBool isOpen_Gempub(const iGempub *d) {
213 return d->arch != NULL; 213 return d->arch != NULL;
214} 214}
215 215
216const iString *property_Gempub(const iGempub *d, enum iGempubProperty prop) {
217 return &d->props[prop];
218}
219
216const iString *coverPageUrl_Gempub(const iGempub *d) { 220const iString *coverPageUrl_Gempub(const iGempub *d) {
217 return &d->baseUrl; 221 return &d->baseUrl;
218} 222}
@@ -232,6 +236,39 @@ const iString *navStartLinkUrl_Gempub(const iGempub *d) {
232 return &((const iGempubNavLink *) constFront_Array(d->navLinks))->url; 236 return &((const iGempubNavLink *) constFront_Array(d->navLinks))->url;
233} 237}
234 238
239size_t navSize_Gempub(const iGempub *d) {
240 parseNavigationLinks_Gempub_(d);
241 return size_Array(d->navLinks);
242}
243
244size_t navIndex_Gempub(const iGempub *d, const iString *url) {
245 parseNavigationLinks_Gempub_(d);
246 const iString *normUrl = withSpacesEncoded_String(url);
247 iConstForEach(Array, i, d->navLinks) {
248 const iGempubNavLink *nav = i.value;
249 if (equalCase_String(&nav->url, normUrl)) {
250 return index_ArrayConstIterator(&i);
251 }
252 }
253 return iInvalidPos;
254}
255
256const iString *navLinkUrl_Gempub(const iGempub *d, size_t index) {
257 parseNavigationLinks_Gempub_(d);
258 if (index < size_Array(d->navLinks)) {
259 return &constValue_Array(d->navLinks, index, iGempubNavLink).url;
260 }
261 return NULL;
262}
263
264const iString *navLinkLabel_Gempub(const iGempub *d, size_t index) {
265 parseNavigationLinks_Gempub_(d);
266 if (index < size_Array(d->navLinks)) {
267 return &constValue_Array(d->navLinks, index, iGempubNavLink).label;
268 }
269 return NULL;
270}
271
235static iBool hasProperty_Gempub_(const iGempub *d, enum iGempubProperty prop) { 272static iBool hasProperty_Gempub_(const iGempub *d, enum iGempubProperty prop) {
236 return !isEmpty_String(&d->props[prop]); 273 return !isEmpty_String(&d->props[prop]);
237} 274}
diff --git a/src/gempub.h b/src/gempub.h
index 6912bcc9..c03cabe6 100644
--- a/src/gempub.h
+++ b/src/gempub.h
@@ -60,5 +60,9 @@ const iString * property_Gempub (const iGempub *, enum iGempubProperty);
60const iString * coverPageUrl_Gempub (const iGempub *); 60const iString * coverPageUrl_Gempub (const iGempub *);
61const iString * indexPageUrl_Gempub (const iGempub *); 61const iString * indexPageUrl_Gempub (const iGempub *);
62const iString * navStartLinkUrl_Gempub (const iGempub *); /* for convenience */ 62const iString * navStartLinkUrl_Gempub (const iGempub *); /* for convenience */
63size_t navSize_Gempub (const iGempub *);
64size_t navIndex_Gempub (const iGempub *, const iString *url);
65const iString * navLinkUrl_Gempub (const iGempub *, size_t index);
66const iString * navLinkLabel_Gempub (const iGempub *, size_t index);
63 67
64extern const char *mimeType_Gempub; 68extern const char *mimeType_Gempub;
diff --git a/src/gmdocument.c b/src/gmdocument.c
index ec406a63..ad8616a3 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
30#include "visited.h" 30#include "visited.h"
31#include "bookmarks.h" 31#include "bookmarks.h"
32#include "app.h" 32#include "app.h"
33#include "defs.h"
33 34
34#include <the_Foundation/ptrarray.h> 35#include <the_Foundation/ptrarray.h>
35#include <the_Foundation/regexp.h> 36#include <the_Foundation/regexp.h>
@@ -400,7 +401,7 @@ static void doLayout_GmDocument_(iGmDocument *d) {
400 static const float bottomMargin[max_GmLineType] = { 401 static const float bottomMargin[max_GmLineType] = {
401 0.0f, 0.333f, 1.0f, 0.5f, 0.5f, 0.5f, 0.5f, 0.25f 402 0.0f, 0.333f, 1.0f, 0.5f, 0.5f, 0.5f, 0.5f, 0.25f
402 }; 403 };
403 static const char *arrow = "\u27a4"; 404 static const char *arrow = rightArrowhead_Icon;
404 static const char *envelope = "\U0001f4e7"; 405 static const char *envelope = "\U0001f4e7";
405 static const char *bullet = "\u2022"; 406 static const char *bullet = "\u2022";
406 static const char *folder = "\U0001f4c1"; 407 static const char *folder = "\U0001f4c1";
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index f354623e..c8aad02b 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -1222,15 +1222,89 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d, iBool
1222 } 1222 }
1223 if (d->sourceGempub) { 1223 if (d->sourceGempub) {
1224 if (equal_String(d->mod.url, coverPageUrl_Gempub(d->sourceGempub))) { 1224 if (equal_String(d->mod.url, coverPageUrl_Gempub(d->sourceGempub))) {
1225 makeFooterButtons_DocumentWidget_(d, (iMenuItem[]){ 1225 if (equalCase_Rangecc(urlScheme_String(d->mod.url), "file")) {
1226 { "Gempub Cover Page", 0, 0, NULL } 1226 iArray *items = collectNew_Array(sizeof(iMenuItem));
1227 }, 1); 1227 pushBack_Array(
1228 items,
1229 &(iMenuItem){ book_Icon " ${gempub.cover.view}",
1230 0,
1231 0,
1232 format_CStr("!open url:%s",
1233 cstr_String(indexPageUrl_Gempub(d->sourceGempub))) });
1234 if (navSize_Gempub(d->sourceGempub) > 0) {
1235 pushBack_Array(
1236 items,
1237 &(iMenuItem){
1238 format_CStr(forwardArrow_Icon " %s",
1239 cstr_String(navLinkLabel_Gempub(d->sourceGempub, 0))),
1240 SDLK_RIGHT,
1241 0,
1242 format_CStr("!open url:%s",
1243 cstr_String(navLinkUrl_Gempub(d->sourceGempub, 0))) });
1244 }
1245 makeFooterButtons_DocumentWidget_(d, constData_Array(items), size_Array(items));
1246 }
1228 if (preloadCoverImage_Gempub(d->sourceGempub, d->doc)) { 1247 if (preloadCoverImage_Gempub(d->sourceGempub, d->doc)) {
1229 redoLayout_GmDocument(d->doc); 1248 redoLayout_GmDocument(d->doc);
1230 updateVisible_DocumentWidget_(d); 1249 updateVisible_DocumentWidget_(d);
1231 invalidate_DocumentWidget_(d); 1250 invalidate_DocumentWidget_(d);
1232 } 1251 }
1233 } 1252 }
1253 else if (equal_String(d->mod.url, indexPageUrl_Gempub(d->sourceGempub))) {
1254 makeFooterButtons_DocumentWidget_(
1255 d,
1256 (iMenuItem[]){ { format_CStr(book_Icon " %s",
1257 cstr_String(property_Gempub(d->sourceGempub,
1258 title_GempubProperty))),
1259 SDLK_LEFT,
1260 0,
1261 format_CStr("!open url:%s",
1262 cstr_String(coverPageUrl_Gempub(d->sourceGempub))) } },
1263 1);
1264 }
1265 else {
1266 /* Navigation buttons. */
1267 iArray *items = collectNew_Array(sizeof(iMenuItem));
1268 const size_t navIndex = navIndex_Gempub(d->sourceGempub, d->mod.url);
1269 if (navIndex != iInvalidPos) {
1270 if (navIndex < navSize_Gempub(d->sourceGempub) - 1) {
1271 pushBack_Array(
1272 items,
1273 &(iMenuItem){
1274 format_CStr(forwardArrow_Icon " %s",
1275 cstr_String(navLinkLabel_Gempub(d->sourceGempub, navIndex + 1))),
1276 SDLK_RIGHT,
1277 0,
1278 format_CStr("!open url:%s",
1279 cstr_String(navLinkUrl_Gempub(d->sourceGempub, navIndex + 1))) });
1280 }
1281 if (navIndex > 0) {
1282 pushBack_Array(
1283 items,
1284 &(iMenuItem){
1285 format_CStr(backArrow_Icon " %s",
1286 cstr_String(navLinkLabel_Gempub(d->sourceGempub, navIndex - 1))),
1287 SDLK_LEFT,
1288 0,
1289 format_CStr("!open url:%s",
1290 cstr_String(navLinkUrl_Gempub(d->sourceGempub, navIndex - 1))) });
1291 }
1292 else if (!equalCase_String(d->mod.url, indexPageUrl_Gempub(d->sourceGempub))) {
1293 pushBack_Array(
1294 items,
1295 &(iMenuItem){
1296 format_CStr(book_Icon " %s",
1297 cstr_String(property_Gempub(d->sourceGempub, title_GempubProperty))),
1298 SDLK_LEFT,
1299 0,
1300 format_CStr("!open url:%s",
1301 cstr_String(coverPageUrl_Gempub(d->sourceGempub))) });
1302 }
1303 }
1304 if (!isEmpty_Array(items)) {
1305 makeFooterButtons_DocumentWidget_(d, constData_Array(items), size_Array(items));
1306 }
1307 }
1234 if (!isCached && prefs_App()->pinSplit && 1308 if (!isCached && prefs_App()->pinSplit &&
1235 equal_String(d->mod.url, indexPageUrl_Gempub(d->sourceGempub))) { 1309 equal_String(d->mod.url, indexPageUrl_Gempub(d->sourceGempub))) {
1236 const iString *navStart = navStartLinkUrl_Gempub(d->sourceGempub); 1310 const iString *navStart = navStartLinkUrl_Gempub(d->sourceGempub);