diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-27 14:16:00 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-27 14:16:00 +0300 |
commit | 29ad5a3de79abd5358be9c4d7967fc3d3ddf0f9a (patch) | |
tree | f49f45a79e97de676dee4e2eaf5e814b6b85e1bf /src | |
parent | 1496a2a027770f0b50bbb7bbcb0c7f11f022b906 (diff) |
DocumentWidget: Copying page contents, URLs
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/documentwidget.c | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index bc1b8e66..271ad274 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <the_Foundation/ptrarray.h> | 15 | #include <the_Foundation/ptrarray.h> |
16 | #include <the_Foundation/regexp.h> | 16 | #include <the_Foundation/regexp.h> |
17 | 17 | ||
18 | #include <SDL_clipboard.h> | ||
18 | #include <SDL_timer.h> | 19 | #include <SDL_timer.h> |
19 | 20 | ||
20 | enum iDocumentState { | 21 | enum iDocumentState { |
@@ -74,9 +75,11 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
74 | makeMenu_Widget(w, | 75 | makeMenu_Widget(w, |
75 | (iMenuItem[]){ { "Back", SDLK_LEFT, KMOD_PRIMARY, "navigate.back" }, | 76 | (iMenuItem[]){ { "Back", SDLK_LEFT, KMOD_PRIMARY, "navigate.back" }, |
76 | { "Forward", SDLK_RIGHT, KMOD_PRIMARY, "navigate.forward" }, | 77 | { "Forward", SDLK_RIGHT, KMOD_PRIMARY, "navigate.forward" }, |
78 | { "Reload", 'r', KMOD_PRIMARY, "navigate.reload" }, | ||
77 | { "---", 0, 0, NULL }, | 79 | { "---", 0, 0, NULL }, |
78 | { "Reload", 'r', KMOD_PRIMARY, "navigate.reload" } }, | 80 | { "Copy", 'c', KMOD_PRIMARY, "copy" }, |
79 | 4); | 81 | { "Copy Link", 0, 0, "document.copylink" } }, |
82 | 6); | ||
80 | } | 83 | } |
81 | 84 | ||
82 | void deinit_DocumentWidget(iDocumentWidget *d) { | 85 | void deinit_DocumentWidget(iDocumentWidget *d) { |
@@ -383,6 +386,28 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
383 | updateVisible_DocumentWidget_(d); | 386 | updateVisible_DocumentWidget_(d); |
384 | refresh_Widget(w); | 387 | refresh_Widget(w); |
385 | } | 388 | } |
389 | else if (isCommand_UserEvent(ev, "copy")) { | ||
390 | if (d->selectMark.start) { | ||
391 | iRangecc mark = d->selectMark; | ||
392 | if (mark.start > mark.end) { | ||
393 | iSwap(const char *, mark.start, mark.end); | ||
394 | } | ||
395 | iString *copied = newRange_String(mark); | ||
396 | SDL_SetClipboardText(cstr_String(copied)); | ||
397 | delete_String(copied); | ||
398 | return iTrue; | ||
399 | } | ||
400 | } | ||
401 | else if (isCommand_Widget(w, ev, "document.copylink")) { | ||
402 | if (d->hoverLink) { | ||
403 | SDL_SetClipboardText(cstr_String( | ||
404 | absoluteUrl_DocumentWidget_(d, linkUrl_GmDocument(d->doc, d->hoverLink->linkId)))); | ||
405 | } | ||
406 | else { | ||
407 | SDL_SetClipboardText(cstr_String(d->url)); | ||
408 | } | ||
409 | return iTrue; | ||
410 | } | ||
386 | else if (isCommand_UserEvent(ev, "document.input.submit")) { | 411 | else if (isCommand_UserEvent(ev, "document.input.submit")) { |
387 | iString *value = collect_String(suffix_Command(command_UserEvent(ev), "value")); | 412 | iString *value = collect_String(suffix_Command(command_UserEvent(ev), "value")); |
388 | urlEncode_String(value); | 413 | urlEncode_String(value); |
@@ -514,26 +539,31 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
514 | return iTrue; | 539 | return iTrue; |
515 | } | 540 | } |
516 | else if (ev->type == SDL_MOUSEMOTION) { | 541 | else if (ev->type == SDL_MOUSEMOTION) { |
517 | const iRect docBounds = documentBounds_DocumentWidget_(d); | 542 | if (isVisible_Widget(d->menu)) { |
518 | const iInt2 mouse = init_I2(ev->motion.x, ev->motion.y); | ||
519 | const iGmRun *oldHoverLink = d->hoverLink; | ||
520 | d->hoverLink = NULL; | ||
521 | const iInt2 hoverPos = addY_I2(sub_I2(mouse, topLeft_Rect(docBounds)), d->scrollY); | ||
522 | iConstForEach(PtrArray, i, &d->visibleLinks) { | ||
523 | const iGmRun *run = i.ptr; | ||
524 | if (contains_Rect(run->bounds, hoverPos)) { | ||
525 | d->hoverLink = run; | ||
526 | break; | ||
527 | } | ||
528 | } | ||
529 | if (d->hoverLink != oldHoverLink) { | ||
530 | refresh_Widget(w); | ||
531 | } | ||
532 | if (!contains_Widget(w, mouse) || contains_Widget(constAs_Widget(d->scroll), mouse)) { | ||
533 | SDL_SetCursor(d->arrowCursor); | 543 | SDL_SetCursor(d->arrowCursor); |
534 | } | 544 | } |
535 | else { | 545 | else { |
536 | SDL_SetCursor(d->hoverLink ? d->handCursor : d->beamCursor); | 546 | const iRect docBounds = documentBounds_DocumentWidget_(d); |
547 | const iInt2 mouse = init_I2(ev->motion.x, ev->motion.y); | ||
548 | const iGmRun *oldHoverLink = d->hoverLink; | ||
549 | d->hoverLink = NULL; | ||
550 | const iInt2 hoverPos = addY_I2(sub_I2(mouse, topLeft_Rect(docBounds)), d->scrollY); | ||
551 | iConstForEach(PtrArray, i, &d->visibleLinks) { | ||
552 | const iGmRun *run = i.ptr; | ||
553 | if (contains_Rect(run->bounds, hoverPos)) { | ||
554 | d->hoverLink = run; | ||
555 | break; | ||
556 | } | ||
557 | } | ||
558 | if (d->hoverLink != oldHoverLink) { | ||
559 | refresh_Widget(w); | ||
560 | } | ||
561 | if (!contains_Widget(w, mouse) || contains_Widget(constAs_Widget(d->scroll), mouse)) { | ||
562 | SDL_SetCursor(d->arrowCursor); | ||
563 | } | ||
564 | else { | ||
565 | SDL_SetCursor(d->hoverLink ? d->handCursor : d->beamCursor); | ||
566 | } | ||
537 | } | 567 | } |
538 | } | 568 | } |
539 | processContextMenuEvent_Widget(d->menu, ev); | 569 | processContextMenuEvent_Widget(d->menu, ev); |