diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-10-17 11:15:14 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-10-17 11:15:14 +0300 |
commit | 2e2b823bfb5d34d42c6b6c1b289193c854459b45 (patch) | |
tree | 345f37aa1b84d8dedb98ff260265b41495e10878 | |
parent | 2f3987f5e54d95658f95c6991b0644bc15eedabf (diff) |
Media and FontPacks (work in progress)
Saving this as the last point of progress. This direction is too complicated: Media needs to be a lot more sophisticated to allow dynamic and interactive media at the level of FontPacks. (A bit like Player handles audio playback.)
This will be reverted. FontPack management will happen using an another method.
-rw-r--r-- | res/arabic.fontpack/fontpack.ini | 2 | ||||
-rw-r--r-- | res/cjk.fontpack/fontpack.ini | 2 | ||||
-rw-r--r-- | res/default.fontpack/fontpack.ini | 2 | ||||
-rw-r--r-- | res/firasans.fontpack/fontpack.ini | 2 | ||||
-rw-r--r-- | res/literata.fontpack/fontpack.ini | 2 | ||||
-rw-r--r-- | res/nunito.fontpack/fontpack.ini | 2 | ||||
-rw-r--r-- | res/tinos.fontpack/fontpack.ini | 2 | ||||
-rw-r--r-- | src/app.c | 61 | ||||
-rw-r--r-- | src/app.h | 2 | ||||
-rw-r--r-- | src/fontpack.c | 69 | ||||
-rw-r--r-- | src/fontpack.h | 10 | ||||
-rw-r--r-- | src/media.c | 32 | ||||
-rw-r--r-- | src/media.h | 2 | ||||
-rw-r--r-- | src/prefs.c | 2 | ||||
-rw-r--r-- | src/prefs.h | 3 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 43 | ||||
-rw-r--r-- | src/ui/documentwidget.h | 3 | ||||
-rw-r--r-- | src/ui/mediaui.c | 48 | ||||
-rw-r--r-- | src/ui/mediaui.h | 7 |
19 files changed, 240 insertions, 56 deletions
diff --git a/res/arabic.fontpack/fontpack.ini b/res/arabic.fontpack/fontpack.ini index 48b40d82..d9087161 100644 --- a/res/arabic.fontpack/fontpack.ini +++ b/res/arabic.fontpack/fontpack.ini | |||
@@ -1,4 +1,4 @@ | |||
1 | version = 1 | 1 | version = 1 |
2 | 2 | ||
3 | [arabic] | 3 | [arabic] |
4 | name = "Noto Sans Arabic UI" | 4 | name = "Noto Sans Arabic UI" |
diff --git a/res/cjk.fontpack/fontpack.ini b/res/cjk.fontpack/fontpack.ini index 6e0d274c..0d74c634 100644 --- a/res/cjk.fontpack/fontpack.ini +++ b/res/cjk.fontpack/fontpack.ini | |||
@@ -1,4 +1,4 @@ | |||
1 | version = 1 | 1 | version = 1 |
2 | 2 | ||
3 | [notosansjp] | 3 | [notosansjp] |
4 | name = "Noto Sans JP" | 4 | name = "Noto Sans JP" |
diff --git a/res/default.fontpack/fontpack.ini b/res/default.fontpack/fontpack.ini index f8ef31ce..68316ef6 100644 --- a/res/default.fontpack/fontpack.ini +++ b/res/default.fontpack/fontpack.ini | |||
@@ -17,8 +17,6 @@ | |||
17 | # `glyphscale` and `voffset` can also be specified separately for the UI and | 17 | # `glyphscale` and `voffset` can also be specified separately for the UI and |
18 | # document domains by prefixing `ui.` or `doc.` to the key. | 18 | # document domains by prefixing `ui.` or `doc.` to the key. |
19 | 19 | ||
20 | version = 1 | ||
21 | |||
22 | [default] | 20 | [default] |
23 | name = "Source Sans" | 21 | name = "Source Sans" |
24 | regular = "SourceSans3-Regular.ttf" | 22 | regular = "SourceSans3-Regular.ttf" |
diff --git a/res/firasans.fontpack/fontpack.ini b/res/firasans.fontpack/fontpack.ini index c6eb4c77..682cad94 100644 --- a/res/firasans.fontpack/fontpack.ini +++ b/res/firasans.fontpack/fontpack.ini | |||
@@ -1,4 +1,4 @@ | |||
1 | version = 1 | 1 | version = 1 |
2 | 2 | ||
3 | [firasans] | 3 | [firasans] |
4 | name = "Fira Sans" | 4 | name = "Fira Sans" |
diff --git a/res/literata.fontpack/fontpack.ini b/res/literata.fontpack/fontpack.ini index 7c29491d..4a264fbf 100644 --- a/res/literata.fontpack/fontpack.ini +++ b/res/literata.fontpack/fontpack.ini | |||
@@ -1,4 +1,4 @@ | |||
1 | version = 1 | 1 | version = 1 |
2 | 2 | ||
3 | [literata] | 3 | [literata] |
4 | name = "Literata" | 4 | name = "Literata" |
diff --git a/res/nunito.fontpack/fontpack.ini b/res/nunito.fontpack/fontpack.ini index 2f2471e1..10ae9516 100644 --- a/res/nunito.fontpack/fontpack.ini +++ b/res/nunito.fontpack/fontpack.ini | |||
@@ -1,4 +1,4 @@ | |||
1 | version = 1 | 1 | version = 1 |
2 | 2 | ||
3 | [nunito] | 3 | [nunito] |
4 | name = "Nunito" | 4 | name = "Nunito" |
diff --git a/res/tinos.fontpack/fontpack.ini b/res/tinos.fontpack/fontpack.ini index a2cf811e..f7b61c9d 100644 --- a/res/tinos.fontpack/fontpack.ini +++ b/res/tinos.fontpack/fontpack.ini | |||
@@ -1,4 +1,4 @@ | |||
1 | version = 1 | 1 | version = 1 |
2 | 2 | ||
3 | [tinos] | 3 | [tinos] |
4 | name = "Tinos" | 4 | name = "Tinos" |
@@ -231,6 +231,9 @@ static iString *serializePrefs_App_(const iApp *d) { | |||
231 | appendFormat_String(str, "linewidth.set arg:%d\n", d->prefs.lineWidth); | 231 | appendFormat_String(str, "linewidth.set arg:%d\n", d->prefs.lineWidth); |
232 | appendFormat_String(str, "linespacing.set arg:%f\n", d->prefs.lineSpacing); | 232 | appendFormat_String(str, "linespacing.set arg:%f\n", d->prefs.lineSpacing); |
233 | appendFormat_String(str, "returnkey.set arg:%d\n", d->prefs.returnKey); | 233 | appendFormat_String(str, "returnkey.set arg:%d\n", d->prefs.returnKey); |
234 | iConstForEach(StringSet, fp, d->prefs.disabledFontPacks) { | ||
235 | appendFormat_String(str, "fontpack.disable id:%s\n", cstr_String(fp.value)); | ||
236 | } | ||
234 | /* TODO: This array belongs in Prefs. It can then be used for command handling as well. */ | 237 | /* TODO: This array belongs in Prefs. It can then be used for command handling as well. */ |
235 | const struct { | 238 | const struct { |
236 | const char * id; | 239 | const char * id; |
@@ -256,21 +259,6 @@ static iString *serializePrefs_App_(const iApp *d) { | |||
256 | iForIndices(i, boolPrefs) { | 259 | iForIndices(i, boolPrefs) { |
257 | appendFormat_String(str, "%s.changed arg:%d\n", boolPrefs[i].id, *boolPrefs[i].value); | 260 | appendFormat_String(str, "%s.changed arg:%d\n", boolPrefs[i].id, *boolPrefs[i].value); |
258 | } | 261 | } |
259 | // appendFormat_String(str, "prefs.animate.changed arg:%d\n", d->prefs.uiAnimations); | ||
260 | // appendFormat_String(str, "prefs.font.smooth.changed arg:%d\n", d->prefs.fontSmoothing); | ||
261 | // appendFormat_String(str, "prefs.gemtext.ansi.changed arg:%d\n", d->prefs.gemtextAnsiEscapes); | ||
262 | // appendFormat_String(str, "prefs.mono.gemini.changed arg:%d\n", d->prefs.monospaceGemini); | ||
263 | // appendFormat_String(str, "prefs.mono.gopher.changed arg:%d\n", d->prefs.monospaceGopher); | ||
264 | // appendFormat_String(str, "prefs.boldlink.dark.changed arg:%d\n", d->prefs.boldLinkDark); | ||
265 | // appendFormat_String(str, "prefs.boldlink.light.changed arg:%d\n", d->prefs.boldLinkLight); | ||
266 | // appendFormat_String(str, "prefs.biglede.changed arg:%d\n", d->prefs.bigFirstParagraph); | ||
267 | // appendFormat_String(str, "prefs.plaintext.wrap.changed arg:%d\n", d->prefs.plainTextWrap); | ||
268 | // appendFormat_String(str, "prefs.sideicon.changed arg:%d\n", d->prefs.sideIcon); | ||
269 | // appendFormat_String(str, "prefs.centershort.changed arg:%d\n", d->prefs.centerShortDocs); | ||
270 | // appendFormat_String(str, "prefs.collapsepreonload.changed arg:%d\n", d->prefs.collapsePreOnLoad); | ||
271 | // appendFormat_String(str, "prefs.hoverlink.changed arg:%d\n", d->prefs.hoverLink); | ||
272 | // appendFormat_String(str, "prefs.bookmarks.addbottom arg:%d\n", d->prefs.addBookmarksToBottom); | ||
273 | // appendFormat_String(str, "prefs.archive.openindex.changed arg:%d\n", d->prefs.openArchiveIndexPages); | ||
274 | appendFormat_String(str, "quoteicon.set arg:%d\n", d->prefs.quoteIcon ? 1 : 0); | 262 | appendFormat_String(str, "quoteicon.set arg:%d\n", d->prefs.quoteIcon ? 1 : 0); |
275 | appendFormat_String(str, "theme.set arg:%d auto:1\n", d->prefs.theme); | 263 | appendFormat_String(str, "theme.set arg:%d auto:1\n", d->prefs.theme); |
276 | appendFormat_String(str, "accent.set arg:%d\n", d->prefs.accent); | 264 | appendFormat_String(str, "accent.set arg:%d\n", d->prefs.accent); |
@@ -381,6 +369,10 @@ static void loadPrefs_App_(iApp *d) { | |||
381 | d->initialWindowRect = init_Rect( | 369 | d->initialWindowRect = init_Rect( |
382 | pos.x, pos.y, argLabel_Command(cmd, "width"), argLabel_Command(cmd, "height")); | 370 | pos.x, pos.y, argLabel_Command(cmd, "width"), argLabel_Command(cmd, "height")); |
383 | } | 371 | } |
372 | else if (equal_Command(cmd, "fontpack.disable")) { | ||
373 | insert_StringSet(d->prefs.disabledFontPacks, | ||
374 | collect_String(suffix_Command(cmd, "id"))); | ||
375 | } | ||
384 | #if !defined (LAGRANGE_ENABLE_DOWNLOAD_EDIT) | 376 | #if !defined (LAGRANGE_ENABLE_DOWNLOAD_EDIT) |
385 | else if (equal_Command(cmd, "downloads")) { | 377 | else if (equal_Command(cmd, "downloads")) { |
386 | continue; /* can't change downloads directory */ | 378 | continue; /* can't change downloads directory */ |
@@ -1119,6 +1111,18 @@ void trimMemory_App(void) { | |||
1119 | iRelease(docs); | 1111 | iRelease(docs); |
1120 | } | 1112 | } |
1121 | 1113 | ||
1114 | iBool findCachedContent_App(const iString *url, iString *mime_out, iBlock *data_out) { | ||
1115 | /* Cached content can be found in MediaRequests of DocumentWidgets (loaded on the currently | ||
1116 | open page) and the DocumentWidget itself. `Media` doesn't store source data, only | ||
1117 | presentation data. */ | ||
1118 | iConstForEach(ObjectList, i, iClob(listDocuments_App(NULL))) { | ||
1119 | if (findCachedContent_DocumentWidget(i.object, url, mime_out, data_out)) { | ||
1120 | return iTrue; | ||
1121 | } | ||
1122 | } | ||
1123 | return iFalse; | ||
1124 | } | ||
1125 | |||
1122 | iLocalDef iBool isWaitingAllowed_App_(iApp *d) { | 1126 | iLocalDef iBool isWaitingAllowed_App_(iApp *d) { |
1123 | if (!isEmpty_Periodic(&d->periodic)) { | 1127 | if (!isEmpty_Periodic(&d->periodic)) { |
1124 | return iFalse; | 1128 | return iFalse; |
@@ -2086,7 +2090,8 @@ const iString *searchQueryUrl_App(const iString *queryStringUnescaped) { | |||
2086 | "%s?%s", cstr_String(&d->prefs.strings[searchUrl_PrefsString]), cstr_String(escaped)); | 2090 | "%s?%s", cstr_String(&d->prefs.strings[searchUrl_PrefsString]), cstr_String(escaped)); |
2087 | } | 2091 | } |
2088 | 2092 | ||
2089 | static void resetFonts_App_(iApp *d) { | 2093 | void resetFonts_App(void) { |
2094 | iApp *d = &app_; | ||
2090 | iConstForEach(PtrArray, win, listWindows_App_(d)) { | 2095 | iConstForEach(PtrArray, win, listWindows_App_(d)) { |
2091 | resetFonts_Text(text_Window(win.ptr)); | 2096 | resetFonts_Text(text_Window(win.ptr)); |
2092 | } | 2097 | } |
@@ -2163,7 +2168,11 @@ iBool handleCommand_App(const char *cmd) { | |||
2163 | return iTrue; | 2168 | return iTrue; |
2164 | } | 2169 | } |
2165 | else if (equal_Command(cmd, "font.reset")) { | 2170 | else if (equal_Command(cmd, "font.reset")) { |
2166 | resetFonts_App_(d); | 2171 | resetFonts_App(); |
2172 | return iTrue; | ||
2173 | } | ||
2174 | else if (equal_Command(cmd, "font.reload")) { | ||
2175 | reload_Fonts(); /* also does font cache reset, window invalidation */ | ||
2167 | return iTrue; | 2176 | return iTrue; |
2168 | } | 2177 | } |
2169 | #if 0 | 2178 | #if 0 |
@@ -2175,7 +2184,7 @@ iBool handleCommand_App(const char *cmd) { | |||
2175 | } | 2184 | } |
2176 | setCStr_String(&d->prefs.symbolFontPath, path); | 2185 | setCStr_String(&d->prefs.symbolFontPath, path); |
2177 | loadUserFonts_Text(); | 2186 | loadUserFonts_Text(); |
2178 | resetFonts_App_(d); | 2187 | resetFonts_App(d); |
2179 | if (!isFrozen) { | 2188 | if (!isFrozen) { |
2180 | postCommand_App("font.changed"); | 2189 | postCommand_App("font.changed"); |
2181 | postCommand_App("window.unfreeze"); | 2190 | postCommand_App("window.unfreeze"); |
@@ -3034,6 +3043,22 @@ iBool handleCommand_App(const char *cmd) { | |||
3034 | } | 3043 | } |
3035 | return iFalse; | 3044 | return iFalse; |
3036 | } | 3045 | } |
3046 | else if (equal_Command(cmd, "media.fontpack.enable")) { | ||
3047 | const iString *packId = collect_String(suffix_Command(cmd, "packid")); | ||
3048 | if (arg_Command(cmd)) { | ||
3049 | remove_StringSet(d->prefs.disabledFontPacks, packId); | ||
3050 | } | ||
3051 | else { | ||
3052 | insert_StringSet(d->prefs.disabledFontPacks, packId); | ||
3053 | } | ||
3054 | resetFonts_App(); | ||
3055 | const iMedia *media = pointerLabel_Command(cmd, "media"); | ||
3056 | if (media) { | ||
3057 | postCommandf_App("media.fontpack.updated id:%u media:%p", | ||
3058 | argU32Label_Command(cmd, "mediaid"), media); | ||
3059 | } | ||
3060 | return iTrue; | ||
3061 | } | ||
3037 | #if defined (LAGRANGE_ENABLE_IPC) | 3062 | #if defined (LAGRANGE_ENABLE_IPC) |
3038 | else if (equal_Command(cmd, "ipc.list.urls")) { | 3063 | else if (equal_Command(cmd, "ipc.list.urls")) { |
3039 | iProcessId pid = argLabel_Command(cmd, "pid"); | 3064 | iProcessId pid = argLabel_Command(cmd, "pid"); |
@@ -99,6 +99,7 @@ iStringSet * listOpenURLs_App (void); /* all tabs */ | |||
99 | iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew); | 99 | iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew); |
100 | void trimCache_App (void); | 100 | void trimCache_App (void); |
101 | void trimMemory_App (void); | 101 | void trimMemory_App (void); |
102 | iBool findCachedContent_App(const iString *url, iString *mime_out, iBlock *data_out); | ||
102 | 103 | ||
103 | iDocumentWidget * document_Root (iRoot *); | 104 | iDocumentWidget * document_Root (iRoot *); |
104 | 105 | ||
@@ -137,6 +138,7 @@ iDocumentWidget * document_Command (const char *cmd); | |||
137 | 138 | ||
138 | void openInDefaultBrowser_App(const iString *url); | 139 | void openInDefaultBrowser_App(const iString *url); |
139 | void revealPath_App (const iString *path); | 140 | void revealPath_App (const iString *path); |
141 | void resetFonts_App (void); | ||
140 | 142 | ||
141 | iMainWindow * mainWindow_App (void); | 143 | iMainWindow * mainWindow_App (void); |
142 | void closePopups_App (void); | 144 | void closePopups_App (void); |
diff --git a/src/fontpack.c b/src/fontpack.c index b135ea43..9603bded 100644 --- a/src/fontpack.c +++ b/src/fontpack.c | |||
@@ -22,6 +22,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
22 | 22 | ||
23 | #include "fontpack.h" | 23 | #include "fontpack.h" |
24 | #include "embedded.h" | 24 | #include "embedded.h" |
25 | #include "ui/window.h" | ||
25 | #include "app.h" | 26 | #include "app.h" |
26 | 27 | ||
27 | #include <the_Foundation/archive.h> | 28 | #include <the_Foundation/archive.h> |
@@ -396,6 +397,24 @@ static iBool load_FontPack_(iFontPack *d, const iString *ini) { | |||
396 | return ok; | 397 | return ok; |
397 | } | 398 | } |
398 | 399 | ||
400 | iBool detect_FontPack(const iBlock *data) { | ||
401 | iBool ok = iFalse; | ||
402 | iArchive *zip = new_Archive(); | ||
403 | if (openData_Archive(zip, data)) { | ||
404 | iString ini; | ||
405 | initBlock_String(&ini, dataCStr_Archive(zip, "fontpack.ini")); | ||
406 | if (isUtf8_Rangecc(range_String(&ini))) { | ||
407 | /* Validate the TOML syntax without actually checking any values. */ | ||
408 | iTomlParser *toml = new_TomlParser(); | ||
409 | ok = parse_TomlParser(toml, &ini); | ||
410 | delete_TomlParser(toml); | ||
411 | } | ||
412 | deinit_String(&ini); | ||
413 | } | ||
414 | iRelease(zip); | ||
415 | return ok; | ||
416 | } | ||
417 | |||
399 | iBool loadArchive_FontPack(iFontPack *d, const iArchive *zip) { | 418 | iBool loadArchive_FontPack(iFontPack *d, const iArchive *zip) { |
400 | d->archive = zip; | 419 | d->archive = zip; |
401 | iBool ok = iFalse; | 420 | iBool ok = iFalse; |
@@ -467,16 +486,24 @@ static void sortSpecs_Fonts_(iFonts *d) { | |||
467 | clear_PtrArray(&d->specOrder); | 486 | clear_PtrArray(&d->specOrder); |
468 | iConstForEach(PtrArray, p, &d->packs) { | 487 | iConstForEach(PtrArray, p, &d->packs) { |
469 | const iFontPack *pack = p.ptr; | 488 | const iFontPack *pack = p.ptr; |
470 | iConstForEach(Array, i, &pack->fonts) { | 489 | if (!contains_StringSet(prefs_App()->disabledFontPacks, &pack->id)) { |
471 | pushBack_PtrArray(&d->specOrder, i.value); | 490 | iConstForEach(Array, i, &pack->fonts) { |
491 | pushBack_PtrArray(&d->specOrder, i.value); | ||
492 | } | ||
472 | } | 493 | } |
473 | } | 494 | } |
474 | sort_Array(&d->specOrder, cmpPriority_FontSpecPtr_); | 495 | sort_Array(&d->specOrder, cmpPriority_FontSpecPtr_); |
475 | } | 496 | } |
476 | 497 | ||
498 | static const iString *userFontsDirectory_Fonts_(const iFonts *d) { | ||
499 | return collect_String(concatCStr_Path(&d->userDir, "fonts")); | ||
500 | } | ||
501 | |||
477 | void init_Fonts(const char *userDir) { | 502 | void init_Fonts(const char *userDir) { |
478 | iFonts *d = &fonts_; | 503 | iFonts *d = &fonts_; |
479 | initCStr_String(&d->userDir, userDir); | 504 | initCStr_String(&d->userDir, userDir); |
505 | const iString *userFontsDir = userFontsDirectory_Fonts_(d); | ||
506 | makeDirs_Path(userFontsDir); | ||
480 | init_PtrArray(&d->packs); | 507 | init_PtrArray(&d->packs); |
481 | d->files = new_ObjectList(); | 508 | d->files = new_ObjectList(); |
482 | init_PtrArray(&d->specOrder); | 509 | init_PtrArray(&d->specOrder); |
@@ -496,7 +523,7 @@ void init_Fonts(const char *userDir) { | |||
496 | "./fonts", | 523 | "./fonts", |
497 | "../share/lagrange", /* Note: These must match CMakeLists.txt install destination */ | 524 | "../share/lagrange", /* Note: These must match CMakeLists.txt install destination */ |
498 | "../../share/lagrange", | 525 | "../../share/lagrange", |
499 | concatPath_CStr(userDir, "fonts"), | 526 | cstr_String(userFontsDir), |
500 | userDir, | 527 | userDir, |
501 | }; | 528 | }; |
502 | const iString *execDir = collectNewRange_String(dirName_Path(execPath_App())); | 529 | const iString *execDir = collectNewRange_String(dirName_Path(execPath_App())); |
@@ -555,7 +582,6 @@ void init_Fonts(const char *userDir) { | |||
555 | void deinit_Fonts(void) { | 582 | void deinit_Fonts(void) { |
556 | iFonts *d = &fonts_; | 583 | iFonts *d = &fonts_; |
557 | unloadFonts_Fonts_(d); | 584 | unloadFonts_Fonts_(d); |
558 | //unloadFiles_Fonts_(d); | ||
559 | iAssert(isEmpty_ObjectList(d->files)); | 585 | iAssert(isEmpty_ObjectList(d->files)); |
560 | deinit_PtrArray(&d->specOrder); | 586 | deinit_PtrArray(&d->specOrder); |
561 | deinit_PtrArray(&d->packs); | 587 | deinit_PtrArray(&d->packs); |
@@ -617,7 +643,18 @@ const iString *infoPage_Fonts(void) { | |||
617 | return str; | 643 | return str; |
618 | } | 644 | } |
619 | 645 | ||
620 | const iFontPack *findPack_Fonts(const iString *path) { | 646 | const iFontPack *pack_Fonts(const char *packId) { |
647 | iFonts *d = &fonts_; | ||
648 | iConstForEach(PtrArray, i, &d->packs) { | ||
649 | const iFontPack *pack = i.ptr; | ||
650 | if (!cmp_String(&pack->id, packId)) { | ||
651 | return pack; | ||
652 | } | ||
653 | } | ||
654 | return NULL; | ||
655 | } | ||
656 | |||
657 | const iFontPack *packByPath_Fonts(const iString *path) { | ||
621 | iFonts *d = &fonts_; | 658 | iFonts *d = &fonts_; |
622 | iConstForEach(PtrArray, i, &d->packs) { | 659 | iConstForEach(PtrArray, i, &d->packs) { |
623 | const iFontPack *pack = i.ptr; | 660 | const iFontPack *pack = i.ptr; |
@@ -628,6 +665,28 @@ const iFontPack *findPack_Fonts(const iString *path) { | |||
628 | return NULL; | 665 | return NULL; |
629 | } | 666 | } |
630 | 667 | ||
668 | void reload_Fonts(void) { | ||
669 | iFonts *d = &fonts_; | ||
670 | iString *userDir = copy_String(&d->userDir); | ||
671 | deinit_Fonts(); /* `d->userDir` is freed */ | ||
672 | init_Fonts(cstr_String(userDir)); | ||
673 | resetFonts_App(); | ||
674 | invalidate_Window(get_MainWindow()); | ||
675 | delete_String(userDir); | ||
676 | } | ||
677 | |||
678 | void install_Fonts(const iString *fontId, const iBlock *data) { | ||
679 | iFonts *d = &fonts_; | ||
680 | iFile *f = new_File(collect_String(concatCStr_Path( | ||
681 | userFontsDirectory_Fonts_(d), format_CStr("%s.fontpack", cstr_String(fontId))))); | ||
682 | if (open_File(f, writeOnly_FileMode)) { | ||
683 | write_File(f, data); | ||
684 | } | ||
685 | iRelease(f); | ||
686 | /* Newly installed fontpacks may have a higher priority that overrides other fonts. */ | ||
687 | reload_Fonts(); | ||
688 | } | ||
689 | |||
631 | iBool preloadLocalFontpackForPreview_Fonts(iGmDocument *doc) { | 690 | iBool preloadLocalFontpackForPreview_Fonts(iGmDocument *doc) { |
632 | iBool wasLoaded = iFalse; | 691 | iBool wasLoaded = iFalse; |
633 | for (size_t linkId = 1; ; linkId++) { | 692 | for (size_t linkId = 1; ; linkId++) { |
diff --git a/src/fontpack.h b/src/fontpack.h index f69e2adc..2fdfa9ab 100644 --- a/src/fontpack.h +++ b/src/fontpack.h | |||
@@ -149,6 +149,7 @@ void setReadOnly_FontPack (iFontPack *, iBool readOnly); | |||
149 | void setStandalone_FontPack (iFontPack *, iBool standalone); | 149 | void setStandalone_FontPack (iFontPack *, iBool standalone); |
150 | void setLoadPath_FontPack (iFontPack *, const iString *path); | 150 | void setLoadPath_FontPack (iFontPack *, const iString *path); |
151 | iBool loadArchive_FontPack (iFontPack *, const iArchive *zip); | 151 | iBool loadArchive_FontPack (iFontPack *, const iArchive *zip); |
152 | iBool detect_FontPack (const iBlock *data); | ||
152 | 153 | ||
153 | iFontPackId id_FontPack (const iFontPack *); | 154 | iFontPackId id_FontPack (const iFontPack *); |
154 | const iPtrArray * listSpecs_FontPack (const iFontPack *); | 155 | const iPtrArray * listSpecs_FontPack (const iFontPack *); |
@@ -159,11 +160,18 @@ iDeclareType(GmDocument) | |||
159 | void init_Fonts (const char *userDir); | 160 | void init_Fonts (const char *userDir); |
160 | void deinit_Fonts (void); | 161 | void deinit_Fonts (void); |
161 | 162 | ||
162 | const iFontPack * findPack_Fonts (const iString *path); | 163 | const iFontPack * pack_Fonts (const char *packId); |
164 | const iFontPack * packByPath_Fonts (const iString *path); | ||
163 | const iFontSpec * findSpec_Fonts (const char *fontId); | 165 | const iFontSpec * findSpec_Fonts (const char *fontId); |
164 | const iPtrArray * listPacks_Fonts (void); | 166 | const iPtrArray * listPacks_Fonts (void); |
165 | const iPtrArray * listSpecs_Fonts (iBool (*filterFunc)(const iFontSpec *)); | 167 | const iPtrArray * listSpecs_Fonts (iBool (*filterFunc)(const iFontSpec *)); |
166 | const iPtrArray * listSpecsByPriority_Fonts (void); | 168 | const iPtrArray * listSpecsByPriority_Fonts (void); |
167 | const iString * infoPage_Fonts (void); | 169 | const iString * infoPage_Fonts (void); |
170 | void install_Fonts (const iString *fontId, const iBlock *data); | ||
171 | void reload_Fonts (void); | ||
168 | 172 | ||
169 | iBool preloadLocalFontpackForPreview_Fonts (iGmDocument *doc); | 173 | iBool preloadLocalFontpackForPreview_Fonts (iGmDocument *doc); |
174 | |||
175 | iLocalDef iBool isInstalled_Fonts(const char *packId) { | ||
176 | return pack_Fonts(packId) != NULL; | ||
177 | } | ||
diff --git a/src/media.c b/src/media.c index 0ce2ac5c..412205a7 100644 --- a/src/media.c +++ b/src/media.c | |||
@@ -312,15 +312,19 @@ void deinit_GmFontpack(iGmFontpack *d) { | |||
312 | 312 | ||
313 | static void loadData_GmFontpack_(iGmFontpack *d, const iBlock *data) { | 313 | static void loadData_GmFontpack_(iGmFontpack *d, const iBlock *data) { |
314 | const iString *loadPath = collect_String(localFilePathFromUrl_String(&d->props.url)); | 314 | const iString *loadPath = collect_String(localFilePathFromUrl_String(&d->props.url)); |
315 | const iFontPack *pack = findPack_Fonts(loadPath); | 315 | const iFontPack *pack = packByPath_Fonts(loadPath); |
316 | d->info.isValid = d->info.isInstalled = pack != NULL; | 316 | d->info.isValid = d->info.isInstalled = pack != NULL; |
317 | d->info.isReadOnly = iFalse; | 317 | d->info.isReadOnly = iFalse; |
318 | d->info.isDisabled = iFalse; | ||
319 | clear_StringList(d->info.names); | ||
320 | clear_String(&d->packId); | ||
318 | if (!pack) { | 321 | if (!pack) { |
319 | /* Let's load it now temporarily and see what's inside. */ | 322 | /* Let's load it now temporarily and see what's inside. */ |
320 | iArchive *zip = new_Archive(); | 323 | iArchive *zip = new_Archive(); |
321 | if (openData_Archive(zip, data)) { | 324 | if (openData_Archive(zip, data)) { |
322 | iFontPack *fp = collect_FontPack(new_FontPack()); | 325 | iFontPack *fp = collect_FontPack(new_FontPack()); |
323 | setLoadPath_FontPack(fp, loadPath); | 326 | setLoadPath_FontPack(fp, loadPath); |
327 | /* TODO: No need to load all the font files here, just the metadata. */ | ||
324 | setStandalone_FontPack(fp, iTrue); | 328 | setStandalone_FontPack(fp, iTrue); |
325 | if (loadArchive_FontPack(fp, zip)) { | 329 | if (loadArchive_FontPack(fp, zip)) { |
326 | d->info.isValid = iTrue; | 330 | d->info.isValid = iTrue; |
@@ -334,6 +338,7 @@ static void loadData_GmFontpack_(iGmFontpack *d, const iBlock *data) { | |||
334 | d->info.packId.id = &d->packId; /* we own this String */ | 338 | d->info.packId.id = &d->packId; /* we own this String */ |
335 | d->info.packId.version = id_FontPack(pack).version; | 339 | d->info.packId.version = id_FontPack(pack).version; |
336 | d->info.isReadOnly = isReadOnly_FontPack(pack); | 340 | d->info.isReadOnly = isReadOnly_FontPack(pack); |
341 | d->info.isDisabled = contains_StringSet(prefs_App()->disabledFontPacks, &d->packId); | ||
337 | } | 342 | } |
338 | iPtrSet *unique = new_PtrSet(); | 343 | iPtrSet *unique = new_PtrSet(); |
339 | iConstForEach(PtrArray, i, listSpecs_FontPack(pack)) { | 344 | iConstForEach(PtrArray, i, listSpecs_FontPack(pack)) { |
@@ -455,7 +460,7 @@ iBool setData_Media(iMedia *d, iGmLinkId linkId, const iString *mime, const iBlo | |||
455 | const iBool isPartial = (flags & partialData_MediaFlag) != 0; | 460 | const iBool isPartial = (flags & partialData_MediaFlag) != 0; |
456 | const iBool allowHide = (flags & allowHide_MediaFlag) != 0; | 461 | const iBool allowHide = (flags & allowHide_MediaFlag) != 0; |
457 | const iBool isDeleting = (!mime || !data); | 462 | const iBool isDeleting = (!mime || !data); |
458 | iMediaId existing = findMediaForLink_Media(d, linkId, none_MediaType);// findLinkImage_Media(d, linkId); | 463 | iMediaId existing = findMediaForLink_Media(d, linkId, none_MediaType); |
459 | const size_t existingIndex = index_MediaId(existing); | 464 | const size_t existingIndex = index_MediaId(existing); |
460 | iBool isNew = iFalse; | 465 | iBool isNew = iFalse; |
461 | if (existing.type == image_MediaType) { | 466 | if (existing.type == image_MediaType) { |
@@ -574,17 +579,34 @@ static iMediaId findMediaPtr_Media_(const iPtrArray *items, enum iMediaType medi | |||
574 | 579 | ||
575 | iMediaId findMediaForLink_Media(const iMedia *d, iGmLinkId linkId, enum iMediaType mediaType) { | 580 | iMediaId findMediaForLink_Media(const iMedia *d, iGmLinkId linkId, enum iMediaType mediaType) { |
576 | /* TODO: Use hashes, this will get very slow if there is a large number of media items. */ | 581 | /* TODO: Use hashes, this will get very slow if there is a large number of media items. */ |
577 | iMediaId mid; | 582 | iMediaId mid = iInvalidMediaId; |
578 | for (int i = 0; i < max_MediaType; i++) { | 583 | for (int i = 0; i < max_MediaType; i++) { |
579 | if (mediaType == i || !mediaType) { | 584 | if (mediaType == i || !mediaType) { |
580 | mid = findMediaPtr_Media_(&d->items[i], i, linkId); | 585 | mid = findMediaPtr_Media_(&d->items[i], i, linkId); |
581 | if (mid.type) { | 586 | if (mid.type) { |
582 | return mid; | 587 | break; |
583 | } | 588 | } |
584 | } | 589 | } |
585 | } | 590 | } |
586 | return iInvalidMediaId; | 591 | return mid; |
592 | } | ||
593 | |||
594 | #if 0 | ||
595 | iMediaId findUrl_Media(const iMedia *d, const iString *url) { | ||
596 | iMediaId mid = iInvalidMediaId; | ||
597 | for (int i = 0; i < max_MediaType; i++) { | ||
598 | for (int j = 0; j < size_PtrArray(&d->items[i]); j++) { | ||
599 | const iGmMediaProps *props = constAt_PtrArray(&d->items[i], j); | ||
600 | if (equal_String(&props->url, url)) { | ||
601 | mid.type = i; | ||
602 | mid.id = j + 1; | ||
603 | break; | ||
604 | } | ||
605 | } | ||
606 | } | ||
607 | return mid; | ||
587 | } | 608 | } |
609 | #endif | ||
588 | 610 | ||
589 | size_t numAudio_Media(const iMedia *d) { | 611 | size_t numAudio_Media(const iMedia *d) { |
590 | return size_PtrArray(&d->items[audio_MediaType]); | 612 | return size_PtrArray(&d->items[audio_MediaType]); |
diff --git a/src/media.h b/src/media.h index 47a4da93..92a46cd3 100644 --- a/src/media.h +++ b/src/media.h | |||
@@ -74,6 +74,7 @@ iBool setData_Media (iMedia *, uint16_t linkId, const iStrin | |||
74 | 74 | ||
75 | size_t memorySize_Media (const iMedia *); | 75 | size_t memorySize_Media (const iMedia *); |
76 | iMediaId findMediaForLink_Media (const iMedia *, uint16_t linkId, enum iMediaType mediaType); | 76 | iMediaId findMediaForLink_Media (const iMedia *, uint16_t linkId, enum iMediaType mediaType); |
77 | //iMediaId findUrl_Media (const iMedia *, const iString *url); | ||
77 | 78 | ||
78 | iMediaId id_Media (const iMedia *, uint16_t linkId, enum iMediaType type); | 79 | iMediaId id_Media (const iMedia *, uint16_t linkId, enum iMediaType type); |
79 | iBool info_Media (const iMedia *, iMediaId mediaId, iGmMediaInfo *info_out); | 80 | iBool info_Media (const iMedia *, iMediaId mediaId, iGmMediaInfo *info_out); |
@@ -114,6 +115,7 @@ struct Impl_FontpackMediaInfo { | |||
114 | iFontPackId packId; | 115 | iFontPackId packId; |
115 | iBool isValid; | 116 | iBool isValid; |
116 | iBool isInstalled; | 117 | iBool isInstalled; |
118 | iBool isDisabled; | ||
117 | iBool isReadOnly; | 119 | iBool isReadOnly; |
118 | size_t sizeInBytes; | 120 | size_t sizeInBytes; |
119 | iStringList *names; | 121 | iStringList *names; |
diff --git a/src/prefs.c b/src/prefs.c index 673470d6..523ec649 100644 --- a/src/prefs.c +++ b/src/prefs.c | |||
@@ -60,6 +60,7 @@ void init_Prefs(iPrefs *d) { | |||
60 | setCStr_String(&d->strings[bodyFont_PrefsString], "default"); | 60 | setCStr_String(&d->strings[bodyFont_PrefsString], "default"); |
61 | setCStr_String(&d->strings[monospaceFont_PrefsString], "iosevka"); | 61 | setCStr_String(&d->strings[monospaceFont_PrefsString], "iosevka"); |
62 | setCStr_String(&d->strings[monospaceDocumentFont_PrefsString], "iosevka-body"); | 62 | setCStr_String(&d->strings[monospaceDocumentFont_PrefsString], "iosevka-body"); |
63 | d->disabledFontPacks = new_StringSet(); | ||
63 | d->fontSmoothing = iTrue; | 64 | d->fontSmoothing = iTrue; |
64 | d->gemtextAnsiEscapes = iFalse; | 65 | d->gemtextAnsiEscapes = iFalse; |
65 | d->monospaceGemini = iFalse; | 66 | d->monospaceGemini = iFalse; |
@@ -88,6 +89,7 @@ void init_Prefs(iPrefs *d) { | |||
88 | } | 89 | } |
89 | 90 | ||
90 | void deinit_Prefs(iPrefs *d) { | 91 | void deinit_Prefs(iPrefs *d) { |
92 | iRelease(d->disabledFontPacks); | ||
91 | iForIndices(i, d->strings) { | 93 | iForIndices(i, d->strings) { |
92 | deinit_String(&d->strings[i]); | 94 | deinit_String(&d->strings[i]); |
93 | } | 95 | } |
diff --git a/src/prefs.h b/src/prefs.h index 70846be4..bbf98370 100644 --- a/src/prefs.h +++ b/src/prefs.h | |||
@@ -22,7 +22,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
22 | 22 | ||
23 | #pragma once | 23 | #pragma once |
24 | 24 | ||
25 | #include <the_Foundation/string.h> | 25 | #include <the_Foundation/stringset.h> |
26 | 26 | ||
27 | #include "gmdocument.h" | 27 | #include "gmdocument.h" |
28 | #include "ui/color.h" | 28 | #include "ui/color.h" |
@@ -87,6 +87,7 @@ struct Impl_Prefs { | |||
87 | int maxCacheSize; /* MB */ | 87 | int maxCacheSize; /* MB */ |
88 | int maxMemorySize; /* MB */ | 88 | int maxMemorySize; /* MB */ |
89 | /* Style */ | 89 | /* Style */ |
90 | iStringSet * disabledFontPacks; | ||
90 | iBool fontSmoothing; | 91 | iBool fontSmoothing; |
91 | iBool gemtextAnsiEscapes; | 92 | iBool gemtextAnsiEscapes; |
92 | iBool monospaceGemini; | 93 | iBool monospaceGemini; |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 924dc0c4..1aca895c 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -2916,6 +2916,27 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
2916 | updateMedia_DocumentWidget_(d); | 2916 | updateMedia_DocumentWidget_(d); |
2917 | return iFalse; | 2917 | return iFalse; |
2918 | } | 2918 | } |
2919 | else if (equal_Command(cmd, "media.fontpack.updated")) { | ||
2920 | iMedia *media = pointerLabel_Command(cmd, "media"); | ||
2921 | if (media == media_GmDocument(d->doc)) { | ||
2922 | /*iGmMediaInfo info; | ||
2923 | if (info_Media(media, | ||
2924 | (iMediaId){ fontpack_MediaType, argU32Label_Command(cmd, "id")}, | ||
2925 | &info)) { | ||
2926 | |||
2927 | }*/ | ||
2928 | |||
2929 | // findCachedContent_App(<#const iString *url#>, <#iString *mime_out#>, <#iBlock *data_out#>) | ||
2930 | // setData_Media(media, | ||
2931 | } | ||
2932 | return iFalse; | ||
2933 | } | ||
2934 | else if (equal_Command(cmd, "media.fontpack.install")) { | ||
2935 | if (pointerLabel_Command(cmd, "media") == media_GmDocument(d->doc)) { | ||
2936 | /* TODO: This is ours, we may have a MediaRequest with the data in memory. */ | ||
2937 | } | ||
2938 | return iFalse; | ||
2939 | } | ||
2919 | else if (equal_Command(cmd, "document.stop") && document_App() == d) { | 2940 | else if (equal_Command(cmd, "document.stop") && document_App() == d) { |
2920 | if (cancelRequest_DocumentWidget_(d, iTrue /* navigate back */)) { | 2941 | if (cancelRequest_DocumentWidget_(d, iTrue /* navigate back */)) { |
2921 | return iTrue; | 2942 | return iTrue; |
@@ -5169,6 +5190,28 @@ void updateSize_DocumentWidget(iDocumentWidget *d) { | |||
5169 | invalidate_DocumentWidget_(d); | 5190 | invalidate_DocumentWidget_(d); |
5170 | } | 5191 | } |
5171 | 5192 | ||
5193 | iBool findCachedContent_DocumentWidget(const iDocumentWidget *d, const iString *url, | ||
5194 | iString *mime_out, iBlock *data_out) { | ||
5195 | if (equal_String(d->mod.url, url) && !isRequestOngoing_DocumentWidget(d)) { | ||
5196 | /* It's the currently open page. */ | ||
5197 | set_String(mime_out, &d->sourceMime); | ||
5198 | set_Block(data_out, &d->sourceContent); | ||
5199 | return iTrue; | ||
5200 | } | ||
5201 | /* Finished media requests are kept in memory while the page is open. */ | ||
5202 | iConstForEach(ObjectList, i, d->media) { | ||
5203 | const iMediaRequest *mr = i.object; | ||
5204 | if (mr->req && | ||
5205 | isFinished_GmRequest(mr->req) && | ||
5206 | equal_String(linkUrl_GmDocument(d->doc, mr->linkId), url)) { | ||
5207 | set_String(mime_out, meta_GmRequest(mr->req)); | ||
5208 | set_Block(data_out, body_GmRequest(mr->req)); | ||
5209 | return iTrue; | ||
5210 | } | ||
5211 | } | ||
5212 | return iFalse; | ||
5213 | } | ||
5214 | |||
5172 | iBeginDefineSubclass(DocumentWidget, Widget) | 5215 | iBeginDefineSubclass(DocumentWidget, Widget) |
5173 | .processEvent = (iAny *) processEvent_DocumentWidget_, | 5216 | .processEvent = (iAny *) processEvent_DocumentWidget_, |
5174 | .draw = (iAny *) draw_DocumentWidget_, | 5217 | .draw = (iAny *) draw_DocumentWidget_, |
diff --git a/src/ui/documentwidget.h b/src/ui/documentwidget.h index 1f2ecfc0..9bfab57a 100644 --- a/src/ui/documentwidget.h +++ b/src/ui/documentwidget.h | |||
@@ -48,6 +48,9 @@ const iString * bookmarkTitle_DocumentWidget (const iDocumentWidget *); | |||
48 | const iString * feedTitle_DocumentWidget (const iDocumentWidget *); | 48 | const iString * feedTitle_DocumentWidget (const iDocumentWidget *); |
49 | int documentWidth_DocumentWidget (const iDocumentWidget *); | 49 | int documentWidth_DocumentWidget (const iDocumentWidget *); |
50 | 50 | ||
51 | iBool findCachedContent_DocumentWidget(const iDocumentWidget *, const iString *url, | ||
52 | iString *mime_out, iBlock *data_out); | ||
53 | |||
51 | enum iDocumentWidgetSetUrlFlags { | 54 | enum iDocumentWidgetSetUrlFlags { |
52 | useCachedContentIfAvailable_DocumentWidgetSetUrlFlag = iBit(1), | 55 | useCachedContentIfAvailable_DocumentWidgetSetUrlFlag = iBit(1), |
53 | openedFromSidebar_DocumentWidgetSetUrlFlag = iBit(2), | 56 | openedFromSidebar_DocumentWidgetSetUrlFlag = iBit(2), |
diff --git a/src/ui/mediaui.c b/src/ui/mediaui.c index aa45d73a..ac9475dd 100644 --- a/src/ui/mediaui.c +++ b/src/ui/mediaui.c | |||
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
28 | #include "paint.h" | 28 | #include "paint.h" |
29 | #include "util.h" | 29 | #include "util.h" |
30 | #include "lang.h" | 30 | #include "lang.h" |
31 | #include "app.h" | ||
31 | 32 | ||
32 | #include <the_Foundation/path.h> | 33 | #include <the_Foundation/path.h> |
33 | #include <the_Foundation/stringlist.h> | 34 | #include <the_Foundation/stringlist.h> |
@@ -281,14 +282,28 @@ void draw_DownloadUI(const iDownloadUI *d, iPaint *p) { | |||
281 | 282 | ||
282 | /*----------------------------------------------------------------------------------------------*/ | 283 | /*----------------------------------------------------------------------------------------------*/ |
283 | 284 | ||
285 | static iMenuItem action_FontpackUI_(const iFontpackUI *d) { | ||
286 | if (d->info.isInstalled) { | ||
287 | return (iMenuItem){ d->info.isDisabled ? "${media.fontpack.enable}" | ||
288 | : close_Icon " ${media.fontpack.disable}", | ||
289 | 0, 0, format_CStr("media.fontpack.enable arg:%d", d->info.isDisabled) }; | ||
290 | } | ||
291 | return (iMenuItem){ d->info.isInstalled ? close_Icon " ${media.fontpack.disable}" | ||
292 | : "${media.fontpack.install}", | ||
293 | 0, 0, | ||
294 | d->info.isInstalled ? "media.fontpack.enable arg:0" : "media.fontpack.install" }; | ||
295 | } | ||
296 | |||
284 | void init_FontpackUI(iFontpackUI *d, const iMedia *media, uint16_t mediaId, iRect bounds) { | 297 | void init_FontpackUI(iFontpackUI *d, const iMedia *media, uint16_t mediaId, iRect bounds) { |
285 | d->media = media; | 298 | d->media = media; |
286 | d->mediaId = mediaId; | 299 | d->mediaId = mediaId; |
300 | fontpackInfo_Media(d->media, (iMediaId){ fontpack_MediaType, d->mediaId }, &d->info); | ||
287 | d->bounds = bounds; | 301 | d->bounds = bounds; |
288 | d->installRect.size = add_I2(measure_Text(uiLabel_FontId, "${media.fontpack.install}").bounds.size, | 302 | iMenuItem action = action_FontpackUI_(d); |
289 | muli_I2(gap2_UI, 3)); | 303 | d->buttonRect.size = add_I2(measure_Text(uiLabel_FontId, action.label).bounds.size, |
290 | d->installRect.pos.x = right_Rect(d->bounds) - gap_UI - d->installRect.size.x; | 304 | muli_I2(gap2_UI, 3)); |
291 | d->installRect.pos.y = mid_Rect(d->bounds).y - d->installRect.size.y / 2; | 305 | d->buttonRect.pos.x = right_Rect(d->bounds) - gap_UI - d->buttonRect.size.x; |
306 | d->buttonRect.pos.y = mid_Rect(d->bounds).y - d->buttonRect.size.y / 2; | ||
292 | } | 307 | } |
293 | 308 | ||
294 | iBool processEvent_FontpackUI(iFontpackUI *d, const SDL_Event *ev) { | 309 | iBool processEvent_FontpackUI(iFontpackUI *d, const SDL_Event *ev) { |
@@ -296,7 +311,12 @@ iBool processEvent_FontpackUI(iFontpackUI *d, const SDL_Event *ev) { | |||
296 | case SDL_MOUSEBUTTONDOWN: | 311 | case SDL_MOUSEBUTTONDOWN: |
297 | case SDL_MOUSEBUTTONUP: { | 312 | case SDL_MOUSEBUTTONUP: { |
298 | const iInt2 pos = init_I2(ev->button.x, ev->button.y); | 313 | const iInt2 pos = init_I2(ev->button.x, ev->button.y); |
299 | if (contains_Rect(d->installRect, pos)) { | 314 | if (contains_Rect(d->buttonRect, pos)) { |
315 | if (ev->type == SDL_MOUSEBUTTONUP) { | ||
316 | postCommandf_App("%s media:%p mediaid:%u packid:%s", | ||
317 | action_FontpackUI_(d).command, | ||
318 | d->media, d->mediaId, cstr_String(d->info.packId.id)); | ||
319 | } | ||
300 | return iTrue; | 320 | return iTrue; |
301 | } | 321 | } |
302 | break; | 322 | break; |
@@ -322,24 +342,22 @@ void draw_FontpackUI(const iFontpackUI *d, iPaint *p) { | |||
322 | /* Draw a background box. */ | 342 | /* Draw a background box. */ |
323 | fillRect_Paint(p, d->bounds, uiBackground_ColorId); | 343 | fillRect_Paint(p, d->bounds, uiBackground_ColorId); |
324 | drawRect_Paint(p, d->bounds, uiSeparator_ColorId); | 344 | drawRect_Paint(p, d->bounds, uiSeparator_ColorId); |
325 | iFontpackMediaInfo info; | ||
326 | fontpackInfo_Media(d->media, (iMediaId){ fontpack_MediaType, d->mediaId }, &info); | ||
327 | iInt2 pos = topLeft_Rect(d->bounds); | 345 | iInt2 pos = topLeft_Rect(d->bounds); |
328 | const char *checks[] = { "\u2610", "\u2611" }; | 346 | const char *checks[] = { "\u2610", "\u2611" }; |
329 | draw_Text(uiContentBold_FontId, pos, uiHeading_ColorId, "\"%s\" v%d", | 347 | draw_Text(uiContentBold_FontId, pos, |
330 | cstr_String(info.packId.id), info.packId.version); | 348 | d->info.isDisabled ? uiText_ColorId : uiHeading_ColorId, "\"%s\" v%d", |
349 | cstr_String(d->info.packId.id), d->info.packId.version); | ||
331 | pos.y += lineHeight_Text(uiContentBold_FontId); | 350 | pos.y += lineHeight_Text(uiContentBold_FontId); |
332 | draw_Text(uiLabelBold_FontId, pos, uiText_ColorId, "%.1f MB, %d fonts %s %s %s", | 351 | draw_Text(uiLabelBold_FontId, pos, uiText_ColorId, "%.1f MB, %d fonts %s %s %s", |
333 | info.sizeInBytes / 1.0e6, size_StringList(info.names), | 352 | d->info.sizeInBytes / 1.0e6, size_StringList(d->info.names), |
334 | // checks[info.isValid], info.isValid ? "No errors" : "Errors detected", | 353 | // checks[info.isValid], info.isValid ? "No errors" : "Errors detected", |
335 | checks[info.isInstalled], info.isInstalled ? "Installed" : "Not installed", | 354 | checks[d->info.isInstalled], d->info.isInstalled ? "Installed" : "Not installed", |
336 | info.isReadOnly ? "Read-Only" : ""); | 355 | d->info.isReadOnly ? "Read-Only" : ""); |
337 | pos.y += lineHeight_Text(uiLabelBold_FontId); | 356 | pos.y += lineHeight_Text(uiLabelBold_FontId); |
338 | iConstForEach(StringList, i, info.names) { | 357 | iConstForEach(StringList, i, d->info.names) { |
339 | drawRange_Text(uiLabel_FontId, pos, uiText_ColorId, range_String(i.value)); | 358 | drawRange_Text(uiLabel_FontId, pos, uiText_ColorId, range_String(i.value)); |
340 | pos.y += lineHeight_Text(uiLabel_FontId); | 359 | pos.y += lineHeight_Text(uiLabel_FontId); |
341 | } | 360 | } |
342 | /* Buttons. */ | 361 | /* Buttons. */ |
343 | drawInlineButton_(p, d->installRect, | 362 | drawInlineButton_(p, d->buttonRect, action_FontpackUI_(d).label, uiLabel_FontId); |
344 | "${media.fontpack.install}", uiLabel_FontId); | ||
345 | } | 363 | } |
diff --git a/src/ui/mediaui.h b/src/ui/mediaui.h index 73de1994..03ea0afc 100644 --- a/src/ui/mediaui.h +++ b/src/ui/mediaui.h | |||
@@ -22,6 +22,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
22 | 22 | ||
23 | #pragma once | 23 | #pragma once |
24 | 24 | ||
25 | #include "../media.h" | ||
26 | |||
25 | #include <the_Foundation/rect.h> | 27 | #include <the_Foundation/rect.h> |
26 | #include <SDL_events.h> | 28 | #include <SDL_events.h> |
27 | 29 | ||
@@ -46,8 +48,6 @@ void draw_PlayerUI (iPlayerUI *, iPaint *p); | |||
46 | 48 | ||
47 | /*----------------------------------------------------------------------------------------------*/ | 49 | /*----------------------------------------------------------------------------------------------*/ |
48 | 50 | ||
49 | iDeclareType(DocumentWidget) | ||
50 | iDeclareType(Media) | ||
51 | iDeclareType(DownloadUI) | 51 | iDeclareType(DownloadUI) |
52 | 52 | ||
53 | struct Impl_DownloadUI { | 53 | struct Impl_DownloadUI { |
@@ -67,8 +67,9 @@ iDeclareType(FontpackUI) | |||
67 | struct Impl_FontpackUI { | 67 | struct Impl_FontpackUI { |
68 | const iMedia *media; | 68 | const iMedia *media; |
69 | uint16_t mediaId; | 69 | uint16_t mediaId; |
70 | iFontpackMediaInfo info; | ||
70 | iRect bounds; | 71 | iRect bounds; |
71 | iRect installRect; | 72 | iRect buttonRect; |
72 | }; | 73 | }; |
73 | 74 | ||
74 | void init_FontpackUI (iFontpackUI *, const iMedia *media, uint16_t mediaId, iRect bounds); | 75 | void init_FontpackUI (iFontpackUI *, const iMedia *media, uint16_t mediaId, iRect bounds); |