jcs
/wikipedia
/amendments
/27
browser: Store link destinations, add clickable links
Print newlines under H3-H5 since we strip whitespace after them.
jcs made amendment 27 over 2 years ago
--- browser.c Mon Sep 5 14:52:16 2022
+++ browser.c Tue Sep 6 10:05:04 2022
@@ -306,7 +306,8 @@ browser_mouse_down(struct focusable *focusable, EventR
Point p;
ControlHandle control;
Rect r;
- short val, adj, page, i, len, part;
+ short val, adj, page, len, part, off;
+ size_t n;
p = event->where;
GlobalToLocal(&p);
@@ -348,6 +349,21 @@ browser_mouse_down(struct focusable *focusable, EventR
HUnlock(browser->te);
if (PtInRect(p, &r)) {
TEClick(p, ((event->modifiers & shiftKey) != 0), browser->te);
+
+ off = TEGetOffset(p, browser->te);
+ for (n = 0; n < browser->links_count; n++) {
+ struct browser_link *link = &browser->links[n];
+
+ if ((link->pos <= off) && (off < link->pos + link->len)) {
+ TESetText(link->link, strlen(link->link), browser->input_te);
+ HLock(browser->input_te);
+ InvalRect(&(*(browser->input_te))->viewRect);
+ HUnlock(browser->input_te);
+ browser->state = BROWSER_STATE_ARTICLE_GET;
+ break;
+ }
+ }
+
browser_update_menu(browser);
return;
}
@@ -518,6 +534,7 @@ browser_print(struct browser *browser, const char *str
size_t n;
short line_height = 0, was_len = 0;
static unsigned long last_style = 0;
+ struct browser_link *link = NULL;
if (scrp_rec_h == NULL) {
scrp_rec_h = xNewHandle(sizeof(short) +
@@ -562,14 +579,33 @@ browser_print(struct browser *browser, const char *str
}
if (style & STYLE_LINK) {
- /* remove link destinations for now */
- for (n = 0; n < len; n++) {
+ if (browser->links_count == browser->links_size) {
+ browser->links_size += 256;
+ browser->links = xreallocarray(browser->links,
+ browser->links_size, sizeof(struct browser_link));
+ memset(&browser->links[browser->links_count], 0,
+ sizeof(struct browser_link) * 256);
+ }
+
+ link = &browser->links[browser->links_count++];
+
+ /* Computer Storage|Storage -> Computer Storage */
+ /* Atari 2600 -> Atari 2600 */
+ for (n = 0; n <= len; n++) {
+ if (n == len) {
+ link->link = xstrndup(str, n, "link");
+ break;
+ }
+
if (str[n] == '|') {
+ link->link = xstrndup(str, n, "link");
str += n + 1;
len -= n + 1;
break;
}
}
+
+ link->len = len;
}
HUnlock(scrp_rec_h);
@@ -616,13 +652,20 @@ te_overflow:
no_overflow:
was_len = (*(browser->te))->teLength;
+ if (style & STYLE_LINK)
+ link->pos = was_len;
+
TESetSelect(SHRT_MAX, SHRT_MAX, browser->te);
if ((last_style & STYLE_ITALIC) && !(style & STYLE_ITALIC))
TEStylInsert(" ", 1, scrp_rec_h, browser->te);
- progress(NULL);
TEStylInsert(str, len, scrp_rec_h, browser->te);
+ if (style & (STYLE_H1 | STYLE_H2))
+ browser_draw_line(browser);
+ else if (style & (STYLE_H3 | STYLE_H4 | STYLE_H5))
+ TEStylInsert("\r", 1, scrp_rec_h, browser->te);
+
if (was_len == 0) {
SetCtlValue(browser->te_scroller, GetCtlMin(browser->te_scroller));
UpdateScrollbarForTE(browser->te_scroller, browser->te, false);
@@ -633,16 +676,18 @@ no_overflow:
last_style = style;
- if (style & (STYLE_H1 | STYLE_H2))
- browser_draw_line(browser);
-
return len;
}
void
browser_clear(struct browser *browser)
{
-
+ size_t n;
+
+ for (n = 0; n < browser->links_count; n++)
+ xfree(&browser->links[n].link);
+
+ xfree(&browser->links);
}
void
--- browser.h Mon Sep 5 20:53:18 2022
+++ browser.h Mon Sep 5 23:34:36 2022
@@ -38,6 +38,12 @@ enum {
#define STYLE_REF (1UL << 8)
#define STYLE_TEMPLATE (1UL << 9)
+struct browser_link {
+ char *link;
+ unsigned short pos;
+ unsigned short len;
+};
+
struct browser {
short state;
WindowPtr win;
@@ -47,6 +53,9 @@ struct browser {
ControlHandle te_scroller;
ListHandle search_results;
struct wikipedia_request *wpr;
+ size_t links_count;
+ size_t links_size;
+ struct browser_link *links;
};
struct browser *browser_init(void);