diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-23 06:10:40 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-23 06:10:40 +0200 |
commit | f79e6735864a16c20d0ed0cc9d79c8c20aeb4816 (patch) | |
tree | 24b2b2399919ad4507fec805da39b333bd795846 | |
parent | 492d80a084685fc30bb8e9ef7689dcdcbe9ab307 (diff) |
Editing bookmark icons
IssueID #140
-rw-r--r-- | res/about/version.gmi | 1 | ||||
-rw-r--r-- | src/bookmarks.c | 25 | ||||
-rw-r--r-- | src/bookmarks.h | 1 | ||||
-rw-r--r-- | src/gmdocument.c | 5 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 3 | ||||
-rw-r--r-- | src/ui/inputwidget.c | 10 | ||||
-rw-r--r-- | 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 @@ | |||
8 | 8 | ||
9 | ## 1.2 | 9 | ## 1.2 |
10 | * Help is opened on first run instead of the "About Lagrange" page to make it easier to discover important Gemini links like the FAQ. | 10 | * Help is opened on first run instead of the "About Lagrange" page to make it easier to discover important Gemini links like the FAQ. |
11 | * Added editable bookmark icons: use your favorite Unicode character as the symbol to represent a bookmarked site in Lagrange. | ||
11 | * Added search engine support: non-URL text entered in the navbar is passed onto the configured search query URL (Preferences > Network). | 12 | * Added search engine support: non-URL text entered in the navbar is passed onto the configured search query URL (Preferences > Network). |
12 | * Short pages are centered vertically on actual page content excluding the top banner. | 13 | * Short pages are centered vertically on actual page content excluding the top banner. |
13 | * Added user preference for aligning all pages to the top of the window. | 14 | * 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 | |||
248 | return changed; | 248 | return changed; |
249 | } | 249 | } |
250 | 250 | ||
251 | iChar siteIcon_Bookmarks(const iBookmarks *d, iRangecc hostName) { | ||
252 | iChar icon = 0; | ||
253 | const size_t hostSize = size_Range(&hostName); | ||
254 | size_t matchingSize = iInvalidSize; /* we'll pick the shortest matching */ | ||
255 | lock_Mutex(d->mtx); | ||
256 | iConstForEach(Hash, i, &d->bookmarks) { | ||
257 | const iBookmark *bm = (const iBookmark *) i.value; | ||
258 | iUrl parts; | ||
259 | init_Url(&parts, &bm->url); | ||
260 | if (!hasTag_Bookmark(bm, "usericon")) { /* TODO: Inefficient! RegExp rebuilt every time. */ | ||
261 | continue; | ||
262 | } | ||
263 | if (size_Range(&hostName) == size_Range(&parts.host) && | ||
264 | iCmpStrNCase(hostName.start, parts.host.start, hostSize) == 0) { | ||
265 | const size_t n = size_String(&bm->url); | ||
266 | if (n < matchingSize && bm->icon) { | ||
267 | matchingSize = n; | ||
268 | icon = bm->icon; | ||
269 | } | ||
270 | } | ||
271 | } | ||
272 | unlock_Mutex(d->mtx); | ||
273 | return icon; | ||
274 | } | ||
275 | |||
251 | iBookmark *get_Bookmarks(iBookmarks *d, uint32_t id) { | 276 | iBookmark *get_Bookmarks(iBookmarks *d, uint32_t id) { |
252 | return (iBookmark *) value_Hash(&d->bookmarks, id); | 277 | return (iBookmark *) value_Hash(&d->bookmarks, id); |
253 | } | 278 | } |
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); | |||
62 | void fetchRemote_Bookmarks (iBookmarks *); | 62 | void fetchRemote_Bookmarks (iBookmarks *); |
63 | void requestFinished_Bookmarks (iBookmarks *, iGmRequest *req); | 63 | void requestFinished_Bookmarks (iBookmarks *, iGmRequest *req); |
64 | iBool updateBookmarkIcon_Bookmarks(iBookmarks *, const iString *url, iChar icon); | 64 | iBool updateBookmarkIcon_Bookmarks(iBookmarks *, const iString *url, iChar icon); |
65 | iChar siteIcon_Bookmarks (const iBookmarks *, iRangecc hostName); | ||
65 | 66 | ||
66 | void save_Bookmarks (const iBookmarks *, const char *dirPath); | 67 | void save_Bookmarks (const iBookmarks *, const char *dirPath); |
67 | uint32_t findUrl_Bookmarks (const iBookmarks *, const iString *url); /* O(n) */ | 68 | 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. */ | |||
27 | #include "ui/metrics.h" | 27 | #include "ui/metrics.h" |
28 | #include "ui/window.h" | 28 | #include "ui/window.h" |
29 | #include "visited.h" | 29 | #include "visited.h" |
30 | #include "bookmarks.h" | ||
30 | #include "app.h" | 31 | #include "app.h" |
31 | 32 | ||
32 | #include <the_Foundation/ptrarray.h> | 33 | #include <the_Foundation/ptrarray.h> |
@@ -1091,6 +1092,10 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) { | |||
1091 | if (equal_CStr(cstr_Block(seed), "gemini.circumlunar.space")) { | 1092 | if (equal_CStr(cstr_Block(seed), "gemini.circumlunar.space")) { |
1092 | d->siteIcon = 0x264a; /* gemini symbol */ | 1093 | d->siteIcon = 0x264a; /* gemini symbol */ |
1093 | } | 1094 | } |
1095 | const iChar userIcon = siteIcon_Bookmarks(bookmarks_App(), urlHost_String(&d->url)); | ||
1096 | if (userIcon) { | ||
1097 | d->siteIcon = userIcon; | ||
1098 | } | ||
1094 | } | 1099 | } |
1095 | #if 0 | 1100 | #if 0 |
1096 | for (int i = tmFirst_ColorId; i < max_ColorId; ++i) { | 1101 | 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) { | |||
670 | const iChar siteIcon = siteIcon_GmDocument(d->doc); | 670 | const iChar siteIcon = siteIcon_GmDocument(d->doc); |
671 | if (siteIcon) { | 671 | if (siteIcon) { |
672 | if (!isEmpty_String(text)) { | 672 | if (!isEmpty_String(text)) { |
673 | prependCStr_String(text, " "); | 673 | prependCStr_String(text, " " restore_ColorEscape); |
674 | } | 674 | } |
675 | prependChar_String(text, siteIcon); | 675 | prependChar_String(text, siteIcon); |
676 | prependCStr_String(text, escape_Color(uiIcon_ColorId)); | ||
676 | } | 677 | } |
677 | const int width = advanceRange_Text(default_FontId, range_String(text)).x; | 678 | const int width = advanceRange_Text(default_FontId, range_String(text)).x; |
678 | if (width <= avail || | 679 | 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) { | |||
346 | resize_Array(&d->text, d->cursor + 1); | 346 | resize_Array(&d->text, d->cursor + 1); |
347 | } | 347 | } |
348 | set_Array(&d->text, d->cursor++, &chr); | 348 | set_Array(&d->text, d->cursor++, &chr); |
349 | if (d->maxLen && d->cursor == d->maxLen) { | 349 | if (d->maxLen > 1 && d->cursor == d->maxLen) { |
350 | iWidget *nextFocus = findFocusable_Widget(w, forward_WidgetFocusDir); | 350 | iWidget *nextFocus = findFocusable_Widget(w, forward_WidgetFocusDir); |
351 | setFocus_Widget(nextFocus == w ? NULL : nextFocus); | 351 | setFocus_Widget(nextFocus == w ? NULL : nextFocus); |
352 | } | 352 | } |
353 | else if (d->maxLen == 1) { | ||
354 | d->cursor = 0; | ||
355 | } | ||
353 | } | 356 | } |
354 | showCursor_InputWidget_(d); | 357 | showCursor_InputWidget_(d); |
355 | refresh_Widget(as_Widget(d)); | 358 | refresh_Widget(as_Widget(d)); |
@@ -675,6 +678,11 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
675 | remove_Array(&d->text, --d->cursor); | 678 | remove_Array(&d->text, --d->cursor); |
676 | contentsWereChanged_InputWidget_(d); | 679 | contentsWereChanged_InputWidget_(d); |
677 | } | 680 | } |
681 | else if (d->cursor == 0 && d->maxLen == 1) { | ||
682 | pushUndo_InputWidget_(d); | ||
683 | clear_Array(&d->text); | ||
684 | contentsWereChanged_InputWidget_(d); | ||
685 | } | ||
678 | showCursor_InputWidget_(d); | 686 | showCursor_InputWidget_(d); |
679 | refresh_Widget(w); | 687 | refresh_Widget(w); |
680 | return iTrue; | 688 | 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 | |||
689 | removeTag_Bookmark(bm, "usericon"); | 689 | removeTag_Bookmark(bm, "usericon"); |
690 | bm->icon = 0; | 690 | bm->icon = 0; |
691 | } | 691 | } |
692 | else if (!hasTag_Bookmark(bm, "usericon")) { | 692 | else { |
693 | addTag_Bookmark(bm, "usericon"); | 693 | if (!hasTag_Bookmark(bm, "usericon")) { |
694 | addTag_Bookmark(bm, "usericon"); | ||
695 | } | ||
694 | bm->icon = first_String(icon); | 696 | bm->icon = first_String(icon); |
695 | } | 697 | } |
696 | postCommand_App("bookmarks.changed"); | 698 | postCommand_App("bookmarks.changed"); |