From f79e6735864a16c20d0ed0cc9d79c8c20aeb4816 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Tue, 23 Feb 2021 06:10:40 +0200 Subject: Editing bookmark icons IssueID #140 --- res/about/version.gmi | 1 + src/bookmarks.c | 25 +++++++++++++++++++++++++ src/bookmarks.h | 1 + src/gmdocument.c | 5 +++++ src/ui/documentwidget.c | 3 ++- src/ui/inputwidget.c | 10 +++++++++- src/ui/sidebarwidget.c | 6 ++++-- 7 files changed, 47 insertions(+), 4 deletions(-) diff --git a/res/about/version.gmi b/res/about/version.gmi index ba94f7e2..c78d3256 100644 --- a/res/about/version.gmi +++ b/res/about/version.gmi @@ -8,6 +8,7 @@ ## 1.2 * Help is opened on first run instead of the "About Lagrange" page to make it easier to discover important Gemini links like the FAQ. +* Added editable bookmark icons: use your favorite Unicode character as the symbol to represent a bookmarked site in Lagrange. * Added search engine support: non-URL text entered in the navbar is passed onto the configured search query URL (Preferences > Network). * Short pages are centered vertically on actual page content excluding the top banner. * Added user preference for aligning all pages to the top of the window. diff --git a/src/bookmarks.c b/src/bookmarks.c index da53b645..5815f447 100644 --- a/src/bookmarks.c +++ b/src/bookmarks.c @@ -248,6 +248,31 @@ iBool updateBookmarkIcon_Bookmarks(iBookmarks *d, const iString *url, iChar icon return changed; } +iChar siteIcon_Bookmarks(const iBookmarks *d, iRangecc hostName) { + iChar icon = 0; + const size_t hostSize = size_Range(&hostName); + size_t matchingSize = iInvalidSize; /* we'll pick the shortest matching */ + lock_Mutex(d->mtx); + iConstForEach(Hash, i, &d->bookmarks) { + const iBookmark *bm = (const iBookmark *) i.value; + iUrl parts; + init_Url(&parts, &bm->url); + if (!hasTag_Bookmark(bm, "usericon")) { /* TODO: Inefficient! RegExp rebuilt every time. */ + continue; + } + if (size_Range(&hostName) == size_Range(&parts.host) && + iCmpStrNCase(hostName.start, parts.host.start, hostSize) == 0) { + const size_t n = size_String(&bm->url); + if (n < matchingSize && bm->icon) { + matchingSize = n; + icon = bm->icon; + } + } + } + unlock_Mutex(d->mtx); + return icon; +} + iBookmark *get_Bookmarks(iBookmarks *d, uint32_t id) { return (iBookmark *) value_Hash(&d->bookmarks, id); } diff --git a/src/bookmarks.h b/src/bookmarks.h index d5182b48..555ff58b 100644 --- a/src/bookmarks.h +++ b/src/bookmarks.h @@ -62,6 +62,7 @@ iBookmark * get_Bookmarks (iBookmarks *, uint32_t id); void fetchRemote_Bookmarks (iBookmarks *); void requestFinished_Bookmarks (iBookmarks *, iGmRequest *req); iBool updateBookmarkIcon_Bookmarks(iBookmarks *, const iString *url, iChar icon); +iChar siteIcon_Bookmarks (const iBookmarks *, iRangecc hostName); void save_Bookmarks (const iBookmarks *, const char *dirPath); uint32_t findUrl_Bookmarks (const iBookmarks *, const iString *url); /* O(n) */ diff --git a/src/gmdocument.c b/src/gmdocument.c index 15ed04b6..3298fecc 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c @@ -27,6 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ui/metrics.h" #include "ui/window.h" #include "visited.h" +#include "bookmarks.h" #include "app.h" #include @@ -1091,6 +1092,10 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) { if (equal_CStr(cstr_Block(seed), "gemini.circumlunar.space")) { d->siteIcon = 0x264a; /* gemini symbol */ } + const iChar userIcon = siteIcon_Bookmarks(bookmarks_App(), urlHost_String(&d->url)); + if (userIcon) { + d->siteIcon = userIcon; + } } #if 0 for (int i = tmFirst_ColorId; i < max_ColorId; ++i) { diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 69461901..2e81838f 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -670,9 +670,10 @@ static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { const iChar siteIcon = siteIcon_GmDocument(d->doc); if (siteIcon) { if (!isEmpty_String(text)) { - prependCStr_String(text, " "); + prependCStr_String(text, " " restore_ColorEscape); } prependChar_String(text, siteIcon); + prependCStr_String(text, escape_Color(uiIcon_ColorId)); } const int width = advanceRange_Text(default_FontId, range_String(text)).x; if (width <= avail || diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index e51ec64b..25c3e145 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c @@ -346,10 +346,13 @@ static void insertChar_InputWidget_(iInputWidget *d, iChar chr) { resize_Array(&d->text, d->cursor + 1); } set_Array(&d->text, d->cursor++, &chr); - if (d->maxLen && d->cursor == d->maxLen) { + if (d->maxLen > 1 && d->cursor == d->maxLen) { iWidget *nextFocus = findFocusable_Widget(w, forward_WidgetFocusDir); setFocus_Widget(nextFocus == w ? NULL : nextFocus); } + else if (d->maxLen == 1) { + d->cursor = 0; + } } showCursor_InputWidget_(d); refresh_Widget(as_Widget(d)); @@ -675,6 +678,11 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { remove_Array(&d->text, --d->cursor); contentsWereChanged_InputWidget_(d); } + else if (d->cursor == 0 && d->maxLen == 1) { + pushUndo_InputWidget_(d); + clear_Array(&d->text); + contentsWereChanged_InputWidget_(d); + } showCursor_InputWidget_(d); refresh_Widget(w); return iTrue; diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index 36aa1235..54812aec 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c @@ -689,8 +689,10 @@ iBool handleBookmarkEditorCommands_SidebarWidget_(iWidget *editor, const char *c removeTag_Bookmark(bm, "usericon"); bm->icon = 0; } - else if (!hasTag_Bookmark(bm, "usericon")) { - addTag_Bookmark(bm, "usericon"); + else { + if (!hasTag_Bookmark(bm, "usericon")) { + addTag_Bookmark(bm, "usericon"); + } bm->icon = first_String(icon); } postCommand_App("bookmarks.changed"); -- cgit v1.2.3