summaryrefslogtreecommitdiff
path: root/src/ui/documentwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r--src/ui/documentwidget.c67
1 files changed, 55 insertions, 12 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index e8a0ded9..aab010c9 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -1,5 +1,8 @@
1#include "documentwidget.h" 1#include "documentwidget.h"
2#include "paint.h" 2#include "paint.h"
3#include "util.h"
4#include "../gemini.h"
5#include "../gmdocument.h"
3 6
4#include <the_Foundation/regexp.h> 7#include <the_Foundation/regexp.h>
5#include <the_Foundation/tlsrequest.h> 8#include <the_Foundation/tlsrequest.h>
@@ -15,9 +18,10 @@ struct Impl_DocumentWidget {
15 iWidget widget; 18 iWidget widget;
16 enum iDocumentState state; 19 enum iDocumentState state;
17 iString *url; 20 iString *url;
18 iString *source;
19 int statusCode;
20 iTlsRequest *request; 21 iTlsRequest *request;
22 int statusCode;
23 iString *newSource;
24 iGmDocument *doc;
21}; 25};
22 26
23iDeclareType(Url) 27iDeclareType(Url)
@@ -31,7 +35,8 @@ struct Impl_Url {
31}; 35};
32 36
33void init_Url(iUrl *d, const iString *text) { 37void init_Url(iUrl *d, const iString *text) {
34 iRegExp *pattern = new_RegExp("(.+)://([^/:?]+)(:[0-9]+)?([^?]*)(\\?.*)?", caseInsensitive_RegExpOption); 38 iRegExp *pattern =
39 new_RegExp("(.+)://([^/:?]+)(:[0-9]+)?([^?]*)(\\?.*)?", caseInsensitive_RegExpOption);
35 iRegExpMatch m; 40 iRegExpMatch m;
36 if (matchString_RegExp(pattern, text, &m)) { 41 if (matchString_RegExp(pattern, text, &m)) {
37 capturedRange_RegExpMatch(&m, 1, &d->protocol); 42 capturedRange_RegExpMatch(&m, 1, &d->protocol);
@@ -59,22 +64,28 @@ void init_DocumentWidget(iDocumentWidget *d) {
59 d->state = blank_DocumentState; 64 d->state = blank_DocumentState;
60 d->url = new_String(); 65 d->url = new_String();
61 d->statusCode = 0; 66 d->statusCode = 0;
62 d->source = new_String();
63 d->request = NULL; 67 d->request = NULL;
64 68 d->newSource = new_String();
69 d->doc = new_GmDocument();
65 setUrl_DocumentWidget(d, collectNewCStr_String("gemini.circumlunar.space/")); 70 setUrl_DocumentWidget(d, collectNewCStr_String("gemini.circumlunar.space/"));
66} 71}
67 72
68void deinit_DocumentWidget(iDocumentWidget *d) { 73void deinit_DocumentWidget(iDocumentWidget *d) {
69 delete_String(d->source);
70 delete_String(d->url); 74 delete_String(d->url);
75 delete_String(d->newSource);
76 iRelease(d->doc);
77}
78
79static int documentWidth_DocumentWidget_(const iDocumentWidget *d) {
80 const iWidget *w = constAs_Widget(d);
81 const iRect bounds = bounds_Widget(w);
82 return bounds.size.x;
71} 83}
72 84
73void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) { 85void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) {
74 /* TODO: lock source during update */ 86 /* TODO: lock source during update */
75 set_String(d->source, source); 87 setSource_GmDocument(d->doc, source, documentWidth_DocumentWidget_(d));
76 printf("%s\n", cstr_String(d->source)); 88 d->state = ready_DocumentState;
77 d->state = layout_DocumentState;
78} 89}
79 90
80static iRangecc getLine_(iRangecc text) { 91static iRangecc getLine_(iRangecc text) {
@@ -92,10 +103,12 @@ static void requestFinished_DocumentWidget_(iAnyObject *obj) {
92 /* First line is the status code. */ { 103 /* First line is the status code. */ {
93 iString *line = newRange_String(respLine); 104 iString *line = newRange_String(respLine);
94 trim_String(line); 105 trim_String(line);
95 printf("response: %s\n", cstr_String(line)); 106 d->statusCode = toInt_String(line);
107 printf("response (%02d): %s\n", d->statusCode, cstr_String(line));
108 /* TODO: post a command with the status code */
96 delete_String(line); 109 delete_String(line);
97 } 110 }
98 setSource_DocumentWidget(d, collect_String(newRange_String(responseRange))); 111 setCStrN_String(d->newSource, responseRange.start, size_Range(&responseRange));
99 delete_Block(response); 112 delete_Block(response);
100 iReleaseLater(d->request); 113 iReleaseLater(d->request);
101 d->request = NULL; 114 d->request = NULL;
@@ -135,14 +148,44 @@ void setUrl_DocumentWidget(iDocumentWidget *d, const iString *url) {
135 148
136static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *ev) { 149static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *ev) {
137 iWidget *w = as_Widget(d); 150 iWidget *w = as_Widget(d);
151 if (isResize_UserEvent(ev)) {
152 setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d));
153 }
138 return processEvent_Widget(w, ev); 154 return processEvent_Widget(w, ev);
139} 155}
140 156
157iDeclareType(DrawContext)
158
159struct Impl_DrawContext {
160 const iDocumentWidget *d;
161 iRect bounds;
162 iPaint paint;
163};
164
165static void drawRun_DrawContext_(void *context, const iGmRun *run) {
166 iDrawContext *d = context;
167 iString text;
168 /* TODO: making a copy is unnecessary; the text routines should accept Rangecc */
169 initRange_String(&text, run->text);
170 drawString_Text(run->font, add_I2(d->bounds.pos, run->bounds.pos), run->color, &text);
171 deinit_String(&text);
172}
173
141static void draw_DocumentWidget_(const iDocumentWidget *d) { 174static void draw_DocumentWidget_(const iDocumentWidget *d) {
142 const iWidget *w = constAs_Widget(d); 175 const iWidget *w = constAs_Widget(d);
143 draw_Widget(w); 176 draw_Widget(w);
177 /* Update the document? */
178 if (!isEmpty_String(d->newSource)) {
179 /* TODO: Do this in the background. However, that requires a text metrics calculator
180 that does not try to cache the glyph bitmaps. */
181 setSource_GmDocument(d->doc, d->newSource, documentWidth_DocumentWidget_(d));
182 clear_String(d->newSource);
183 iConstCast(iDocumentWidget *, d)->state = ready_DocumentState;
184 }
144 if (d->state != ready_DocumentState) return; 185 if (d->state != ready_DocumentState) return;
145 /* TODO: lock source during draw */ 186 iDrawContext ctx = {.d = d, .bounds = bounds_Widget(w) };
187 init_Paint(&ctx.paint);
188 render_GmDocument(d->doc, (iRangei){ 0, height_Rect(ctx.bounds) }, drawRun_DrawContext_, &ctx);
146} 189}
147 190
148iBeginDefineSubclass(DocumentWidget, Widget) 191iBeginDefineSubclass(DocumentWidget, Widget)