diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-29 08:08:02 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-29 08:08:02 +0300 |
commit | 4d8e45d99f13f0bff476b999708f793b41fd2927 (patch) | |
tree | 2a41dfb02e617460b4c1379f45040f9c32a2e2d7 /src | |
parent | 4deb72ba6ea6c055dff69d74669887f30ea01e54 (diff) |
Viewing image URLs
When the opened URL is just an image, generate a simple document for it.
Diffstat (limited to 'src')
-rw-r--r-- | src/gmdocument.c | 2 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 81 |
2 files changed, 54 insertions, 29 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c index 4a3f8e06..15d81603 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c | |||
@@ -448,7 +448,7 @@ static void doLayout_GmDocument_(iGmDocument *d) { | |||
448 | if (width_Rect(run.visBounds) > maxSize.x) { | 448 | if (width_Rect(run.visBounds) > maxSize.x) { |
449 | /* Don't scale the image up. */ | 449 | /* Don't scale the image up. */ |
450 | run.visBounds.size.y = run.visBounds.size.y * maxSize.x / width_Rect(run.visBounds); | 450 | run.visBounds.size.y = run.visBounds.size.y * maxSize.x / width_Rect(run.visBounds); |
451 | run.visBounds.size.x = img->size.x; | 451 | run.visBounds.size.x = maxSize.x; |
452 | run.visBounds.pos.x = run.bounds.size.x / 2 - width_Rect(run.visBounds) / 2; | 452 | run.visBounds.pos.x = run.bounds.size.x / 2 - width_Rect(run.visBounds) / 2; |
453 | run.bounds.size.y = run.visBounds.size.y; | 453 | run.bounds.size.y = run.visBounds.size.y; |
454 | } | 454 | } |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index f63e98bf..98d9eca5 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -211,6 +211,32 @@ static int scrollMax_DocumentWidget_(const iDocumentWidget *d) { | |||
211 | 2 * d->pageMargin * gap_UI; | 211 | 2 * d->pageMargin * gap_UI; |
212 | } | 212 | } |
213 | 213 | ||
214 | static void updateHover_DocumentWidget_(iDocumentWidget *d, iInt2 mouse) { | ||
215 | const iRect docBounds = documentBounds_DocumentWidget_(d); | ||
216 | const iGmRun *oldHoverLink = d->hoverLink; | ||
217 | d->hoverLink = NULL; | ||
218 | const iInt2 hoverPos = addY_I2(sub_I2(mouse, topLeft_Rect(docBounds)), d->scrollY); | ||
219 | if (d->state == ready_DocumentState) { | ||
220 | iConstForEach(PtrArray, i, &d->visibleLinks) { | ||
221 | const iGmRun *run = i.ptr; | ||
222 | if (contains_Rect(run->bounds, hoverPos)) { | ||
223 | d->hoverLink = run; | ||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | if (d->hoverLink != oldHoverLink) { | ||
229 | refresh_Widget(as_Widget(d)); | ||
230 | } | ||
231 | if (!contains_Widget(constAs_Widget(d), mouse) || | ||
232 | contains_Widget(constAs_Widget(d->scroll), mouse)) { | ||
233 | SDL_SetCursor(d->arrowCursor); | ||
234 | } | ||
235 | else { | ||
236 | SDL_SetCursor(d->hoverLink ? d->handCursor : d->beamCursor); | ||
237 | } | ||
238 | } | ||
239 | |||
214 | static void updateVisible_DocumentWidget_(iDocumentWidget *d) { | 240 | static void updateVisible_DocumentWidget_(iDocumentWidget *d) { |
215 | const iRangei visRange = visibleRange_DocumentWidget_(d); | 241 | const iRangei visRange = visibleRange_DocumentWidget_(d); |
216 | const iRect bounds = bounds_Widget(as_Widget(d)); | 242 | const iRect bounds = bounds_Widget(as_Widget(d)); |
@@ -221,6 +247,7 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) { | |||
221 | docSize > 0 ? height_Rect(bounds) * size_Range(&visRange) / docSize : 0); | 247 | docSize > 0 ? height_Rect(bounds) * size_Range(&visRange) / docSize : 0); |
222 | clear_PtrArray(&d->visibleLinks); | 248 | clear_PtrArray(&d->visibleLinks); |
223 | render_GmDocument(d->doc, visRange, addVisibleLink_DocumentWidget_, d); | 249 | render_GmDocument(d->doc, visRange, addVisibleLink_DocumentWidget_, d); |
250 | updateHover_DocumentWidget_(d, mouseCoord_Window(get_Window())); | ||
224 | } | 251 | } |
225 | 252 | ||
226 | static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { | 253 | static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { |
@@ -293,8 +320,21 @@ static void updateSource_DocumentWidget_(iDocumentWidget *d) { | |||
293 | setFormat_GmDocument(d->doc, gemini_GmDocumentFormat); | 320 | setFormat_GmDocument(d->doc, gemini_GmDocumentFormat); |
294 | } | 321 | } |
295 | else if (startsWith_String(mime, "image/")) { | 322 | else if (startsWith_String(mime, "image/")) { |
296 | /* TODO: Make a simple document with an image. */ | 323 | if (isFinished_GmRequest(d->request)) { |
297 | clear_String(&str); | 324 | /* Make a simple document with an image. */ |
325 | const char *imageTitle = "Image"; | ||
326 | iUrl parts; | ||
327 | init_Url(&parts, url_GmRequest(d->request)); | ||
328 | if (!isEmpty_Range(&parts.path)) { | ||
329 | imageTitle = baseName_Path(collect_String(newRange_String(parts.path))); | ||
330 | } | ||
331 | format_String( | ||
332 | &str, "=> %s %s\n", cstr_String(url_GmRequest(d->request)), imageTitle); | ||
333 | setImage_GmDocument(d->doc, 1, mime, body_GmRequest(d->request)); | ||
334 | } | ||
335 | else { | ||
336 | clear_String(&str); | ||
337 | } | ||
298 | } | 338 | } |
299 | else { | 339 | else { |
300 | showErrorPage_DocumentWidget_(d, unsupportedMimeType_GmStatusCode); | 340 | showErrorPage_DocumentWidget_(d, unsupportedMimeType_GmStatusCode); |
@@ -714,29 +754,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
714 | SDL_SetCursor(d->arrowCursor); | 754 | SDL_SetCursor(d->arrowCursor); |
715 | } | 755 | } |
716 | else { | 756 | else { |
717 | const iRect docBounds = documentBounds_DocumentWidget_(d); | 757 | updateHover_DocumentWidget_(d, init_I2(ev->motion.x, ev->motion.y)); |
718 | const iInt2 mouse = init_I2(ev->motion.x, ev->motion.y); | ||
719 | const iGmRun *oldHoverLink = d->hoverLink; | ||
720 | d->hoverLink = NULL; | ||
721 | const iInt2 hoverPos = addY_I2(sub_I2(mouse, topLeft_Rect(docBounds)), d->scrollY); | ||
722 | if (d->state == ready_DocumentState) { | ||
723 | iConstForEach(PtrArray, i, &d->visibleLinks) { | ||
724 | const iGmRun *run = i.ptr; | ||
725 | if (contains_Rect(run->bounds, hoverPos)) { | ||
726 | d->hoverLink = run; | ||
727 | break; | ||
728 | } | ||
729 | } | ||
730 | } | ||
731 | if (d->hoverLink != oldHoverLink) { | ||
732 | refresh_Widget(w); | ||
733 | } | ||
734 | if (!contains_Widget(w, mouse) || contains_Widget(constAs_Widget(d->scroll), mouse)) { | ||
735 | SDL_SetCursor(d->arrowCursor); | ||
736 | } | ||
737 | else { | ||
738 | SDL_SetCursor(d->hoverLink ? d->handCursor : d->beamCursor); | ||
739 | } | ||
740 | } | 758 | } |
741 | } | 759 | } |
742 | if (ev->type == SDL_MOUSEBUTTONDOWN) { | 760 | if (ev->type == SDL_MOUSEBUTTONDOWN) { |
@@ -885,13 +903,20 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) { | |||
885 | if (!isEmpty_Rect(run->bounds)) { | 903 | if (!isEmpty_Rect(run->bounds)) { |
886 | iGmImageInfo info; | 904 | iGmImageInfo info; |
887 | imageInfo_GmDocument(doc, linkImage_GmDocument(doc, run->linkId), &info); | 905 | imageInfo_GmDocument(doc, linkImage_GmDocument(doc, run->linkId), &info); |
906 | iString text; | ||
907 | init_String(&text); | ||
908 | format_String(&text, "%s \u2014 %d x %d \u2014 %.1fMB", | ||
909 | info.mime, info.size.x, info.size.y, info.numBytes / 1.0e6f); | ||
910 | if (findMediaRequest_DocumentWidget_(d->widget, run->linkId)) { | ||
911 | appendFormat_String( | ||
912 | &text, " %s\u2715", run == d->widget->hoverLink ? white_ColorEscape : ""); | ||
913 | } | ||
888 | drawAlign_Text(default_FontId, | 914 | drawAlign_Text(default_FontId, |
889 | add_I2(topRight_Rect(run->bounds), origin), | 915 | add_I2(topRight_Rect(run->bounds), origin), |
890 | fg, | 916 | fg, |
891 | right_Alignment, | 917 | right_Alignment, |
892 | "%s \u2014 %d x %d \u2014 %.1fMB %s \u2715", | 918 | "%s", cstr_String(&text)); |
893 | info.mime, info.size.x, info.size.y, info.numBytes / 1.0e6f, | 919 | deinit_String(&text); |
894 | run == d->widget->hoverLink ? white_ColorEscape : ""); | ||
895 | } | 920 | } |
896 | } | 921 | } |
897 | else if (run == d->widget->hoverLink) { | 922 | else if (run == d->widget->hoverLink) { |